New windows-gui, initial release
authoroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 28 Sep 2005 00:33:08 +0000 (00:33 +0000)
committeroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 28 Sep 2005 00:33:08 +0000 (00:33 +0000)
18 files changed:
gpsbabel/win32/gui-2/GPSBabelGUI.ico [new file with mode: 0644]
gpsbabel/win32/gui-2/GPSBabelGUI2.dof [new file with mode: 0644]
gpsbabel/win32/gui-2/GPSBabelGUI2.dpr [new file with mode: 0644]
gpsbabel/win32/gui-2/about.dfm [new file with mode: 0644]
gpsbabel/win32/gui-2/about.pas [new file with mode: 0644]
gpsbabel/win32/gui-2/common.pas [new file with mode: 0644]
gpsbabel/win32/gui-2/filter.dfm [new file with mode: 0644]
gpsbabel/win32/gui-2/filter.pas [new file with mode: 0644]
gpsbabel/win32/gui-2/gnugettext.pas [new file with mode: 0644]
gpsbabel/win32/gui-2/gnugettextD4.pas [new file with mode: 0644]
gpsbabel/win32/gui-2/locale/de/LC_MESSAGES/default.po [new file with mode: 0644]
gpsbabel/win32/gui-2/locale/fr/LC_MESSAGES/default.po [new file with mode: 0644]
gpsbabel/win32/gui-2/main.dfm [new file with mode: 0644]
gpsbabel/win32/gui-2/main.pas [new file with mode: 0644]
gpsbabel/win32/gui-2/readme.dfm [new file with mode: 0644]
gpsbabel/win32/gui-2/readme.pas [new file with mode: 0644]
gpsbabel/win32/gui-2/template.po [new file with mode: 0644]
gpsbabel/win32/gui-2/utils.pas [new file with mode: 0644]

diff --git a/gpsbabel/win32/gui-2/GPSBabelGUI.ico b/gpsbabel/win32/gui-2/GPSBabelGUI.ico
new file mode 100644 (file)
index 0000000..76a19fd
Binary files /dev/null and b/gpsbabel/win32/gui-2/GPSBabelGUI.ico differ
diff --git a/gpsbabel/win32/gui-2/GPSBabelGUI2.dof b/gpsbabel/win32/gui-2/GPSBabelGUI2.dof
new file mode 100644 (file)
index 0000000..f23784e
--- /dev/null
@@ -0,0 +1,84 @@
+[Compiler]\r
+A=0\r
+B=0\r
+C=0\r
+D=0\r
+E=0\r
+F=0\r
+G=1\r
+H=1\r
+I=0\r
+J=1\r
+K=0\r
+L=0\r
+M=0\r
+N=1\r
+O=1\r
+P=1\r
+Q=0\r
+R=0\r
+S=0\r
+T=0\r
+U=0\r
+V=0\r
+W=0\r
+X=1\r
+Y=0\r
+Z=1\r
+ShowHints=0\r
+ShowWarnings=0\r
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
+[Linker]\r
+MapFile=0\r
+OutputObjs=0\r
+ConsoleApp=1\r
+DebugInfo=0\r
+RemoteSymbols=0\r
+MinStackSize=16384\r
+MaxStackSize=1048576\r
+ImageBase=4194304\r
+ExeDescription=\r
+[Directories]\r
+OutputDir=\r
+UnitOutputDir=\r
+PackageDLLOutputDir=\r
+PackageDCPOutputDir=\r
+SearchPath=\r
+Packages=vcl;rtl;vclx;dbrtl;adortl;vcldb;bdertl;vcldbx;teeui;teedb;tee;ibxpress;visualclx;visualdbclx;dsnap;vclactnband\r
+Conditionals=MSWINDOWS\r
+DebugSourceDirs=\r
+UsePackages=0\r
+[Parameters]\r
+RunParams=\r
+HostApplication=\r
+[Version Info]\r
+IncludeVerInfo=1\r
+AutoIncBuild=0\r
+MajorVer=0\r
+MinorVer=1\r
+Release=0\r
+Build=0\r
+Debug=0\r
+PreRelease=0\r
+Special=0\r
+Private=0\r
+DLL=0\r
+Locale=1031\r
+CodePage=1252\r
+[Version Info Keys]\r
+CompanyName=\r
+FileDescription=GPSBabel Frontend\r
+FileVersion=0.1.0.0\r
+InternalName=\r
+LegalCopyright=\r
+LegalTrademarks=\r
+OriginalFilename=\r
+ProductName=GPSBabel\r
+ProductVersion=1.0.0.0\r
+Comments=\r
+[HistoryLists\hlConditionals]\r
+Count=1\r
+Item0=MSWINDOWS\r
+[HistoryLists\hlUnitAliases]\r
+Count=1\r
+Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;\r
diff --git a/gpsbabel/win32/gui-2/GPSBabelGUI2.dpr b/gpsbabel/win32/gui-2/GPSBabelGUI2.dpr
new file mode 100644 (file)
index 0000000..5146fc0
--- /dev/null
@@ -0,0 +1,54 @@
+program GPSBabelGUI2;\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+uses\r
+  gnugettext in 'gnugettext.pas',\r
+  gnugettextD4 in 'gnugettextD4.pas',\r
+  Windows,\r
+  SysUtils,\r
+  classes,\r
+  Forms,\r
+  main in 'main.pas' {frmMain},\r
+  utils in 'utils.pas',\r
+  common in 'common.pas',\r
+  filter in 'filter.pas' {frmFilter},\r
+  about in 'about.pas' {frmAbout},\r
+  readme in 'readme.pas' {frmReadme};\r
+\r
+{$R *.RES}\r
+\r
+(*\r
+!!!\r
+gpsbabel.exe -w -i gdb -f "C:\TEMP\2005 Pfunds total.gdb" -x duplicate,shortname -o pathaway -F "C:\TEMP\2005 Pfunds total.pdb"\r
+gpsbabel: Unable to allocate -16056 bytes of memory.\r
+!!!\r
+*)\r
+\r
+begin\r
+  AddDomainForResourceString('delphi');\r
+\r
+  UseLanguage('en');                 // for testing\r
+\r
+  Application.Initialize;\r
+  Application.CreateForm(TfrmMain, frmMain);\r
+  Application.CreateForm(TfrmReadme, frmReadme);\r
+  Application.CreateForm(TfrmFilter, frmFilter);\r
+  Application.CreateForm(TfrmAbout, frmAbout);\r
+  Application.Run;\r
+end.\r
diff --git a/gpsbabel/win32/gui-2/about.dfm b/gpsbabel/win32/gui-2/about.dfm
new file mode 100644 (file)
index 0000000..745de05
Binary files /dev/null and b/gpsbabel/win32/gui-2/about.dfm differ
diff --git a/gpsbabel/win32/gui-2/about.pas b/gpsbabel/win32/gui-2/about.pas
new file mode 100644 (file)
index 0000000..247c594
--- /dev/null
@@ -0,0 +1,56 @@
+unit about;\r
+\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+interface\r
+\r
+uses\r
+  gnugettextD4,\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  StdCtrls, Buttons, ExtCtrls;\r
+\r
+type\r
+  TfrmAbout = class(TForm)\r
+    pnClient: TPanel;\r
+    Image1: TImage;\r
+    StaticText1: TStaticText;\r
+    StaticText2: TStaticText;\r
+    pnBottom: TPanel;\r
+    BitBtn1: TBitBtn;\r
+    procedure FormCreate(Sender: TObject);\r
+  private\r
+    { Private declarations }\r
+  public\r
+    { Public declarations }\r
+  end;\r
+\r
+var\r
+  frmAbout: TfrmAbout;\r
+\r
+implementation\r
+\r
+{$R *.DFM}\r
+\r
+procedure TfrmAbout.FormCreate(Sender: TObject);\r
+begin\r
+  gnugettextD4.TranslateComponent(SELF);\r
+end;\r
+\r
+end.\r
\ No newline at end of file
diff --git a/gpsbabel/win32/gui-2/common.pas b/gpsbabel/win32/gui-2/common.pas
new file mode 100644 (file)
index 0000000..e4f40d1
--- /dev/null
@@ -0,0 +1,269 @@
+unit common;\r
+\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+interface\r
+\r
+uses\r
+  Windows, SysUtils, Classes, Messages;\r
+\r
+const\r
+  WM_STARTUP = WM_USER + 1;\r
+\r
+const\r
+  SREG_TARGET_DIR = 'Target:Directory';\r
+  SREG_SOURCE_DIR = 'Source:Directory';\r
+\r
+  SREG_TARGET_DEV = 'Target:Device';\r
+  SREG_SOURCE_DEV = 'Source:Device';\r
+\r
+  SREG_SOURCE_FMT = 'Source:FileFormat';\r
+  SREG_TARGET_FMT = 'Target:FileFormat';\r
+\r
+  SREG_SOURCE_SER = 'Source:DeviceFormat';\r
+  SREG_TARGET_SER = 'Target:DeviceFormat';\r
+\r
+const\r
+  Profile: array[0..8] of string =\r
+  ('?',\r
+   SREG_SOURCE_DIR,\r
+   SREG_SOURCE_FMT,\r
+   SREG_SOURCE_DEV,\r
+   SREG_SOURCE_SER,\r
+   SREG_TARGET_DIR,\r
+   SREG_TARGET_FMT,\r
+   SREG_TARGET_DEV,\r
+   SREG_TARGET_SER);\r
+\r
+type\r
+  PFileInfo = ^TFileInfo;\r
+  TFileInfo = record\r
+    Descr: string;\r
+    Ext:   string;\r
+    internal: string;\r
+    Capas: Integer;\r
+  end;\r
+\r
+type\r
+  TCapabilities = class(TStringList)\r
+  private\r
+    FList: TStrings;\r
+    procedure AddFormat(const Line: string);\r
+    function GetList: TStrings;\r
+    procedure SetList(const Value: TStrings);\r
+  public\r
+    function CanReadAny(Index: Integer): Boolean;\r
+    function CanWriteAny(Index: Integer): Boolean;\r
+    function GetDescr(Index: Integer): string;\r
+    function GetExt(const Descr: string): string;\r
+    function GetCaps(const Descr: string): Integer;\r
+    function GetName(const Descr: string): string;\r
+    function IsDevice(Index: Integer): Boolean;\r
+    function IsFile(Index: Integer): Boolean;\r
+  property\r
+    List: TStrings read GetList write SetList;\r
+  end;\r
+\r
+type\r
+  eGPSBabelError = class(Exception);\r
+\r
+var\r
+  gpsbabel_exe: string;\r
+\r
+implementation\r
+\r
+{ TCapabilities }\r
+\r
+procedure TCapabilities.AddFormat(const Line: string);\r
+var\r
+  index: Integer;\r
+  buff: array[0..1023] of Char;\r
+  cin, cend: PChar;\r
+  i: Integer;\r
+\r
+  scaps: string;\r
+  ext: string;\r
+  comment: string;\r
+  name: string;\r
+  internal: string;\r
+  \r
+  caps: Integer;\r
+\r
+  info: PFileInfo;\r
+\r
+begin\r
+  StrPCopy(buff, Line);\r
+  StrCat(buff, #9);\r
+\r
+  cin := @buff;\r
+  index := 0;\r
+\r
+  while (true) do\r
+  begin\r
+    cend := StrScan(cin, #9);\r
+    if (cend = nil) then break;\r
+    cend^ := #0;\r
+\r
+    case index of\r
+      0: internal := StrPas(cin);\r
+      1: scaps := StrPas(cin);\r
+      2: name := StrPas(cin);\r
+      3: ext := StrPas(cin);\r
+    else\r
+      begin\r
+        comment := StrPas(cin);\r
+        if (Length(comment) = 0) or (Length(name) = 0) then break;\r
+        \r
+        if (comment[1] = '?') then break;\r
+        \r
+        caps := 0;\r
+        for i := 1 to Length(scaps) do\r
+          if (scaps[i] <> '-') then caps := caps or (1 shl (i - 1));\r
+\r
+         New(info);\r
+         info.Descr := comment;\r
+         info.Ext := ext;\r
+         info.internal := internal;\r
+         info.Capas := caps;\r
+         \r
+         i := SELF.Add(name);\r
+         SELF.PutObject(i, Pointer(info));\r
+         break;\r
+       end;\r
+    end;\r
+\r
+    index := index + 1;\r
+    cin := cend + 1;\r
+  end;\r
+end;\r
+\r
+function TCapabilities.CanReadAny(Index: Integer): Boolean;\r
+var\r
+  caps: Integer;\r
+begin\r
+  caps := PFileInfo(SELF.Objects[Index]).Capas;\r
+  Result := caps and (1 or 4 or 16) <> 0;\r
+end;\r
+\r
+function TCapabilities.CanWriteAny(Index: Integer): Boolean;\r
+var\r
+  caps: Integer;\r
+begin\r
+  caps := PFileInfo(SELF.Objects[Index]).Capas;\r
+  Result := caps and (2 or 8 or 32) <> 0;\r
+end;\r
+\r
+function TCapabilities.GetCaps(const Descr: string): Integer;\r
+var\r
+  info: PFileInfo;\r
+  i: Integer;\r
+begin\r
+  for i := 0 to Count - 1 do\r
+  begin\r
+    info := PFileInfo(Objects[i]);\r
+    if (AnsiCompareText(info.Descr, Descr) = 0) then\r
+    begin\r
+      Result := info.Capas;\r
+      Exit;\r
+    end;\r
+  end;\r
+  Result := 0;\r
+end;\r
+\r
+function TCapabilities.GetDescr(Index: Integer): string;\r
+var\r
+  info: PFileInfo;\r
+begin\r
+  info := PFileInfo(Objects[Index]);\r
+  Result := info.Descr;\r
+end;\r
+\r
+function TCapabilities.GetExt(const Descr: string): string;\r
+var\r
+  i: Integer;\r
+  info: PFileInfo;\r
+begin\r
+  for i := 0 to Count - 1 do\r
+  begin\r
+    info := PFileInfo(Objects[i]);\r
+    if (AnsiCompareText(info.Descr, Descr) = 0) then\r
+    begin\r
+      Result := info.Ext;\r
+      Exit;\r
+    end;\r
+  end;\r
+  Result := '.*';\r
+end;\r
+\r
+function TCapabilities.GetList: TStrings;\r
+begin\r
+  Result := TStringList.Create;\r
+end;\r
+\r
+function TCapabilities.GetName(const Descr: string): string;\r
+var\r
+  i: Integer;\r
+  info: PFileInfo;\r
+begin\r
+  for i := 0 to Count - 1 do\r
+  begin\r
+    info := PFileInfo(Objects[i]);\r
+    if (AnsiCompareText(info.Descr, Descr) = 0) then\r
+    begin\r
+      Result := SELF[i];\r
+      Exit;\r
+    end;\r
+  end;\r
+  Result := 'unknown';\r
+end;\r
+\r
+function TCapabilities.IsDevice(Index: Integer): Boolean;\r
+var\r
+  info: PFileInfo;\r
+begin\r
+  info := PFileInfo(Objects[Index]);\r
+  Result := (AnsiCompareText(info.Internal, 'serial') = 0);\r
+end;\r
+\r
+function TCapabilities.IsFile(Index: Integer): Boolean;\r
+var\r
+  info: PFileInfo;\r
+begin\r
+  info := PFileInfo(Objects[Index]);\r
+  Result := (AnsiCompareText(info.Internal, 'file') = 0);\r
+end;\r
+\r
+procedure TCapabilities.SetList(const Value: TStrings);\r
+var\r
+  i: Integer;\r
+  s: string;\r
+begin\r
+  Clear;\r
+  for i := 0 to Value.Count - 1 do\r
+  begin\r
+    s := Value.Strings[i];\r
+    AddFormat(s);\r
+  end;\r
+end;\r
+\r
+initialization\r
+\r
+  gpsbabel_exe := SysUtils.ExtractFilePath(ParamStr(0)) + 'gpsbabel.exe';\r
+\r
+end.\r
diff --git a/gpsbabel/win32/gui-2/filter.dfm b/gpsbabel/win32/gui-2/filter.dfm
new file mode 100644 (file)
index 0000000..596daab
Binary files /dev/null and b/gpsbabel/win32/gui-2/filter.dfm differ
diff --git a/gpsbabel/win32/gui-2/filter.pas b/gpsbabel/win32/gui-2/filter.pas
new file mode 100644 (file)
index 0000000..1d1f585
--- /dev/null
@@ -0,0 +1,323 @@
+unit filter;\r
+\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+interface\r
+\r
+uses\r
+  gnugettextD4,\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  StdCtrls, ComCtrls, Buttons, Mask, ExtCtrls;\r
+\r
+type\r
+  TfrmFilter = class(TForm)\r
+    gbTracks: TGroupBox;\r
+    cbTrackTitle: TCheckBox;\r
+    edTrackTitle: TEdit;\r
+    cbTrackSplit: TCheckBox;\r
+    cbTrackTime: TCheckBox;\r
+    udTimeHours: TUpDown;\r
+    edTrackTimeHours: TEdit;\r
+    udTimeMinutes: TUpDown;\r
+    edTrackTimeMinutes: TEdit;\r
+    edTrackTimeDays: TEdit;\r
+    udTimeDays: TUpDown;\r
+    edTrackTimeSeconds: TEdit;\r
+    udTimeSeconds: TUpDown;\r
+    lbTimePlusMinus: TLabel;\r
+    lbTimeDays: TLabel;\r
+    lbTimeHours: TLabel;\r
+    lbTimeMinutes: TLabel;\r
+    lbTimeSeconds: TLabel;\r
+    cbTrackStart: TCheckBox;\r
+    dtpTrackStartDate: TDateTimePicker;\r
+    dtpTrackStartTime: TDateTimePicker;\r
+    cbTrackStop: TCheckBox;\r
+    dtpTrackStopDate: TDateTimePicker;\r
+    dtpTrackStopTime: TDateTimePicker;\r
+    gbRoutes: TGroupBox;\r
+    cbRouteSimplify: TCheckBox;\r
+    lbRouteSimplifyCount: TLabel;\r
+    edRoutesSimplifyMaxPoints: TMaskEdit;\r
+    udRouteSompifyMaxPoints: TUpDown;\r
+    lbRouteSimplifyText: TLabel;\r
+    pnBottom: TPanel;\r
+    btnOK: TBitBtn;\r
+    gbWaypoints: TGroupBox;\r
+    cbWayptMergeDupLoc: TCheckBox;\r
+    cbReverse: TCheckBox;\r
+    cbWayptMergeDupNames: TCheckBox;\r
+    cbWayptMergeDistance: TCheckBox;\r
+    cobWayptMergeDist: TComboBox;\r
+    edWayptMergeDist: TEdit;\r
+    cbWayptSort: TCheckBox;\r
+    cbWayptMergeDups: TCheckBox;\r
+    btnCancel: TBitBtn;\r
+    cbTrackPack: TCheckBox;\r
+    cbTrackMerge: TCheckBox;\r
+    BitBtn1: TBitBtn;\r
+    Image1: TImage;\r
+    procedure cbTrackTimeClick(Sender: TObject);\r
+    procedure FormCreate(Sender: TObject);\r
+    procedure cbTrackTitleClick(Sender: TObject);\r
+    procedure btnOKClick(Sender: TObject);\r
+    procedure cbTrackStartClick(Sender: TObject);\r
+    procedure cbTrackStopClick(Sender: TObject);\r
+    procedure cbRouteSimplifyClick(Sender: TObject);\r
+    procedure cbTrackPackClick(Sender: TObject);\r
+    procedure cbTrackMergeClick(Sender: TObject);\r
+    procedure cbWayptMergeDistanceClick(Sender: TObject);\r
+    procedure cbWayptMergeDupsClick(Sender: TObject);\r
+  private\r
+    { Private-Deklarationen }\r
+    lTrackTimeList: TList;\r
+    FTracksEnabled: Boolean;\r
+    function AnyChecked(Control: TWinControl): Boolean;\r
+    procedure EnableList(List: TList; Enable: Boolean = True);\r
+    procedure SetTracksEnabled(const Value: Boolean);\r
+    function AllValid: Boolean;\r
+  public\r
+    { Public-Deklarationen }\r
+    function CmdLine: string;\r
+    property TracksEnabled: Boolean read FTracksEnabled write SetTracksEnabled;\r
+  end;\r
+\r
+var\r
+  frmFilter: TfrmFilter = nil;\r
+\r
+implementation\r
+\r
+{$R *.DFM}\r
+\r
+procedure FixPosition(AControl, LeftFromMe: TControl; IsText: Boolean);\r
+begin\r
+  AControl.Left := LeftFromMe.Left + LeftFromMe.Width;\r
+  if (IsText) then\r
+    AControl.Left := AControl.Left + 4;\r
+end;\r
+\r
+procedure TfrmFilter.cbTrackTimeClick(Sender: TObject);\r
+begin\r
+  EnableList(lTrackTimeList, cbTrackTime.Checked);\r
+end;\r
+\r
+procedure TfrmFilter.EnableList(List: TList; Enable: Boolean);\r
+var\r
+  i: Integer;\r
+  o: TObject;\r
+begin\r
+  for i := 0 to List.Count - 1 do\r
+  begin\r
+    o := Pointer(List.Items[i]);\r
+    if (o is TControl) then\r
+      with o as TControl do\r
+        Enabled := Enable;\r
+  end;\r
+end;\r
+\r
+procedure TfrmFilter.FormCreate(Sender: TObject);\r
+begin\r
+  gnugettextD4.TranslateComponent(SELF);\r
+  \r
+  lTrackTimeList := TList.Create;\r
+  \r
+  lTrackTimeList.Add(edTrackTimeDays);\r
+  lTrackTimeList.Add(edTrackTimeHours);\r
+  lTrackTimeList.Add(edTrackTimeMinutes);\r
+  lTrackTimeList.Add(edTrackTimeSeconds);\r
+\r
+  EnableList(lTrackTimeList, False);\r
+\r
+  FixPosition(edTrackTimeDays, lbTimePlusMinus, True);\r
+  FixPosition(udTimeDays, edTrackTimeDays, False);\r
+  FixPosition(lbTimeDays, udTimeDays, True);\r
+\r
+  FixPosition(edTrackTimeHours, lbTimeDays, True);\r
+  FixPosition(udTimeHours, edTrackTimeHours, False);\r
+  FixPosition(lbTimeHours, udTimeHours, True);\r
+\r
+  FixPosition(edTrackTimeMinutes, lbTimeHours, True);\r
+  FixPosition(udTimeMinutes, edTrackTimeMinutes, False);\r
+  FixPosition(lbTimeMinutes, udTimeMinutes, True);\r
+\r
+  FixPosition(edTrackTimeSeconds, lbTimeMinutes, True);\r
+  FixPosition(udTimeSeconds, edTrackTimeSeconds, False);\r
+  FixPosition(lbTimeSeconds, udTimeSeconds, True);\r
+\r
+  cobWayptMergeDist.Text := _('Miles');\r
+end;\r
+\r
+procedure TfrmFilter.cbTrackTitleClick(Sender: TObject);\r
+begin\r
+  edTrackTitle.Enabled := cbTrackTitle.Checked;\r
+end;\r
+\r
+function TfrmFilter.CmdLine: string;\r
+\r
+  procedure SimpleOption(var CmdLine: string; CheckBox: TCheckBox; const Option: string);\r
+  begin\r
+    if (CheckBox.Checked) then\r
+      CmdLine := Format('%s -x %s', [CmdLine, Option]);\r
+  end;\r
+\r
+var\r
+  s: string;\r
+begin\r
+  Result := '';\r
+  if not AnyChecked(Self) then Exit;\r
+\r
+  Result := '';\r
+\r
+  if AnyChecked(gbWaypoints) then\r
+  begin\r
+    if cbWayptMergeDups.Checked and\r
+       (cbWayptMergeDupNames.Checked or cbWayptMergeDupLoc.Checked) then\r
+    begin\r
+      Result := Format('%s -x %s', [Result, 'duplicate']);\r
+      if cbWayptMergeDupNames.Checked then\r
+        Result := Format('%s,%s', [Result, 'shortname']);\r
+      if cbWayptMergeDupLoc.Checked then\r
+        Result := Format('%s,%s', [Result, 'location']);\r
+\r
+      SimpleOption(Result, cbWayptSort, 'sort');\r
+    end;\r
+  end;\r
+\r
+  if AnyChecked(gbTracks) then\r
+  begin\r
+    Result := Format('%s -x %s', [Result, 'track']);\r
+    if cbTrackTitle.Checked then\r
+      Result := Format('%s,title="%s"', [Result, edTrackTitle.Text]);\r
+\r
+    if cbTrackTime.Checked then\r
+    begin\r
+      s := Format('%sd%sh%sm%ss',\r
+        [edTrackTimeDays.Text, edTrackTimeHours.Text,\r
+         edTrackTimeMinutes.Text, edTrackTimeSeconds.Text]);\r
+      if (s <> '0d0h0m0s') then\r
+        Result := Format('%s,move=%s', [Result, s]);\r
+    end;\r
+\r
+    if cbTrackPack.Checked then\r
+      Result := Format('%s,pack', [Result])\r
+    else if cbTrackMerge.Checked then\r
+      Result := Format('%s,merge', [Result]);\r
+\r
+    if cbTrackSplit.Checked then\r
+      Result := Format('%s,split', [Result]);\r
+\r
+    if cbTrackStart.Checked then\r
+      Result := Format('%s,start=%s', [\r
+        Result,\r
+        FormatDateTime('yyyymmddhhnnss',\r
+          Int(dtpTrackStartDate.DateTime) + Frac(dtpTrackStartTime.DateTime))]);\r
+    if cbTrackStop.Checked then\r
+      Result := Format('%s,stop=%s', [\r
+        Result,\r
+        FormatDateTime('yyyymmddhhnnss',\r
+          Int(dtpTrackStopDate.DateTime) + Frac(dtpTrackStopTime.DateTime))]);\r
+  end;\r
+\r
+  if AnyChecked(gbRoutes) then\r
+  begin\r
+    if cbRouteSimplify.Checked then\r
+      Result := Format('%s -x simplify,count=%s',\r
+        [Result, Trim(edRoutesSimplifyMaxPoints.Text)]);\r
+\r
+    SimpleOption(Result, cbReverse, 'reverse');\r
+  end;\r
+end;\r
+\r
+function TfrmFilter.AnyChecked(Control: TWinControl): Boolean;\r
+var\r
+  i: Integer;\r
+  c: TWinControl;\r
+begin\r
+  Result := False;\r
+  for i := 0 to Self.ComponentCount - 1 do\r
+  begin\r
+    c := Pointer(Self.Components[i]);\r
+    if not(c.InheritsFrom(TWinControl)) then Continue;\r
+    if (c.parent <> Control) then Continue;\r
+\r
+    if ((c is TCheckBox) and TCheckBox(c).Enabled) then\r
+      Result := TCheckBox(c).Checked else\r
+    if ((c is TGroupBox) and c.Enabled) then\r
+      Result := AnyChecked(c);\r
+    if (Result) then Exit;\r
+  end;\r
+end;\r
+\r
+procedure TfrmFilter.SetTracksEnabled(const Value: Boolean);\r
+begin\r
+  FTracksEnabled := Value;\r
+  gbTracks.Enabled := Value;\r
+end;\r
+\r
+function TfrmFilter.AllValid: Boolean;\r
+begin\r
+  Result := True;\r
+end;\r
+\r
+procedure TfrmFilter.btnOKClick(Sender: TObject);\r
+begin\r
+  if AllValid then ModalResult := mrOK;\r
+end;\r
+\r
+procedure TfrmFilter.cbTrackStartClick(Sender: TObject);\r
+begin\r
+  dtpTrackStartDate.Enabled := cbTrackStart.Checked;\r
+  dtpTrackStartTime.Enabled := cbTrackStart.Checked;\r
+end;\r
+\r
+procedure TfrmFilter.cbTrackStopClick(Sender: TObject);\r
+begin\r
+  dtpTrackStopDate.Enabled := cbTrackStop.Checked;\r
+  dtpTrackStopTime.Enabled := cbTrackStop.Checked;\r
+end;\r
+\r
+procedure TfrmFilter.cbRouteSimplifyClick(Sender: TObject);\r
+begin\r
+  edRoutesSimplifyMaxPoints.Enabled := cbRouteSimplify.Checked;\r
+end;\r
+\r
+procedure TfrmFilter.cbTrackPackClick(Sender: TObject);\r
+begin\r
+  if cbTrackPack.Checked then\r
+    cbTrackMerge.Checked := False;\r
+end;\r
+\r
+procedure TfrmFilter.cbTrackMergeClick(Sender: TObject);\r
+begin\r
+  if cbTrackMerge.Checked then cbTrackPack.Checked := False;\r
+end;\r
+\r
+procedure TfrmFilter.cbWayptMergeDistanceClick(Sender: TObject);\r
+begin\r
+  edWayptMergeDist.Enabled := cbWayptMergeDistance.Checked;\r
+  cobWayptMergeDist.Enabled := cbWayptMergeDistance.Checked;\r
+end;\r
+\r
+procedure TfrmFilter.cbWayptMergeDupsClick(Sender: TObject);\r
+begin\r
+  cbWayptMergeDupLoc.Enabled := cbWayptMergeDups.Checked;\r
+  cbWayptMergeDupNames.Enabled := cbWayptMergeDups.Checked;\r
+end;\r
+\r
+end.\r
diff --git a/gpsbabel/win32/gui-2/gnugettext.pas b/gpsbabel/win32/gui-2/gnugettext.pas
new file mode 100644 (file)
index 0000000..603bfc0
--- /dev/null
@@ -0,0 +1,2903 @@
+unit gnugettext;\r
+(**************************************************************)\r
+(*                                                            *)\r
+(*  (C) Copyright by Lars B. Dybdahl and others               *)\r
+(*  E-mail: Lars@dybdahl.dk, phone +45 70201241               *)\r
+(*  File version: $Date: 2005-09-28 00:33:08 $                *)\r
+(*  Revision: $Revision: 1.1 $                          *)\r
+(*                                                            *)\r
+(*  Contributors: Peter Thornqvist, Troy Wolbrink,            *)\r
+(*                Frank Andreas de Groot, Igor Siticov,       *)\r
+(*                Jacques Garcia Vazquez                      *)\r
+(*                                                            *)\r
+(*  See http://dybdahl.dk/dxgettext/ for more information     *)\r
+(*                                                            *)\r
+(**************************************************************)\r
+\r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are met:\r
+//\r
+// The names of any contributor may not be used to endorse or promote\r
+// products derived from this software without specific prior written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+interface\r
+\r
+// If the conditional define DXGETTEXTDEBUG is defined, debugging log is activated.\r
+// Use DefaultInstance.DebugLogToFile() to write the log to a file.\r
+{ $define DXGETTEXTDEBUG}\r
+\r
+{$ifdef VER100}\r
+  // Delphi 3\r
+  {$DEFINE DELPHI5OROLDER}\r
+  {$DEFINE DELPHI6OROLDER}\r
+{$endif}\r
+{$ifdef VER110}\r
+  // C++ Builder 3\r
+  {$DEFINE DELPHI5OROLDER}\r
+  {$DEFINE DELPHI6OROLDER}\r
+{$endif}\r
+{$ifdef VER120}\r
+  // Delphi 4\r
+  {$DEFINE DELPHI5OROLDER}\r
+  {$DEFINE DELPHI6OROLDER}\r
+{$endif}\r
+{$ifdef VER125}\r
+  // C++ Builder 4\r
+  {$DEFINE DELPHI5OROLDER}\r
+  {$DEFINE DELPHI6OROLDER}\r
+{$endif}\r
+{$ifdef VER130}\r
+  // Delphi 5\r
+  {$DEFINE DELPHI5OROLDER}\r
+  {$DEFINE DELPHI6OROLDER}\r
+  {$ifdef WIN32}\r
+  {$DEFINE MSWINDOWS}\r
+  {$endif}\r
+{$endif}\r
+{$ifdef VER135}\r
+  // C++ Builder 5\r
+  {$DEFINE DELPHI5OROLDER}\r
+  {$DEFINE DELPHI6OROLDER}\r
+  {$ifdef WIN32}\r
+  {$DEFINE MSWINDOWS}\r
+  {$endif}\r
+{$endif}\r
+{$ifdef VER140}\r
+  // Delphi 6\r
+{$ifdef MSWINDOWS}\r
+  {$DEFINE DELPHI6OROLDER}\r
+{$endif}\r
+{$endif}\r
+{$ifdef VER150}\r
+  // Delphi 7\r
+{$endif}\r
+\r
+uses\r
+{$ifdef DELPHI5OROLDER}\r
+  gnugettextD4, \r
+{$endif}\r
+\r
+{$ifdef MSWINDOWS}\r
+  Windows,\r
+{$else}\r
+  Libc,\r
+{$endif}\r
+  Classes, SysUtils, TypInfo;\r
+\r
+(*****************************************************************************)\r
+(*                                                                           *)\r
+(*  MAIN API                                                                 *)\r
+(*                                                                           *)\r
+(*****************************************************************************)\r
+\r
+// Main GNU gettext functions. See documentation for instructions on how to use them.\r
+function _(const szMsgId: widestring): widestring;\r
+function gettext(const szMsgId: widestring): widestring;\r
+function dgettext(const szDomain: string; const szMsgId: widestring): widestring;\r
+function dngettext(const szDomain: string; const singular,plural: widestring; Number:longint): widestring;\r
+function ngettext(const singular,plural: widestring; Number:longint): widestring;\r
+procedure textdomain(const szDomain: string);\r
+function getcurrenttextdomain: string;\r
+procedure bindtextdomain(const szDomain: string; const szDirectory: string);\r
+\r
+// Set language to use\r
+procedure UseLanguage(LanguageCode: string);\r
+function GetCurrentLanguage:string;\r
+\r
+// Translates a component (form, frame etc.) to the currently selected language.\r
+// Put TranslateComponent(self) in the OnCreate event of all your forms.\r
+// See the manual for documentation on these functions\r
+type\r
+  TTranslator=procedure (obj:TObject) of object;\r
+\r
+procedure TP_Ignore(AnObject:TObject; const name:string);\r
+procedure TP_IgnoreClass (IgnClass:TClass);\r
+procedure TP_IgnoreClassProperty (IgnClass:TClass;const propertyname:string);\r
+procedure TP_GlobalIgnoreClass (IgnClass:TClass);\r
+procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;const propertyname:string);\r
+procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator);\r
+procedure TranslateComponent(AnObject: TComponent; const TextDomain:string='');\r
+procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string='');\r
+\r
+// Add more domains that resourcestrings can be extracted from. If a translation\r
+// is not found in the default domain, this domain will be searched, too.\r
+// This is useful for adding mo files for certain runtime libraries and 3rd\r
+// party component libraries\r
+procedure AddDomainForResourceString (const domain:string);\r
+procedure RemoveDomainForResourceString (const domain:string);\r
+\r
+// Unicode-enabled way to get resourcestrings, automatically translated\r
+// Use like this: ws:=LoadResStringW(@NameOfResourceString);\r
+function LoadResString(ResStringRec: PResStringRec): widestring;\r
+function LoadResStringA(ResStringRec: PResStringRec): ansistring;\r
+function LoadResStringW(ResStringRec: PResStringRec): widestring;\r
+\r
+// This returns an empty string if not translated or translator name is not specified.\r
+function GetTranslatorNameAndEmail:widestring;\r
+\r
+\r
+(*****************************************************************************)\r
+(*                                                                           *)\r
+(*  ADVANCED FUNCTIONALITY                                                   *)\r
+(*                                                                           *)\r
+(*****************************************************************************)\r
+\r
+const\r
+  DefaultTextDomain = 'default';\r
+\r
+var\r
+  ExecutableFilename:string;    // This is set to paramstr(0) or the name of the DLL you are creating.\r
+\r
+type\r
+  EGnuGettext=class(Exception);\r
+  EGGProgrammingError=class(EGnuGettext);\r
+  EGGComponentError=class(EGnuGettext);\r
+  EGGIOError=class(EGnuGettext);\r
+  EGGAnsi2WideConvError=class(EGnuGettext);\r
+\r
+// This function will turn resourcestring hooks on or off, eventually with BPL file support.\r
+// Please do not activate BPL file support when the package is in design mode.\r
+const AutoCreateHooks=true;\r
+procedure HookIntoResourceStrings (enabled:boolean=true; SupportPackages:boolean=false);\r
+\r
+\r
+\r
+\r
+(*****************************************************************************)\r
+(*                                                                           *)\r
+(*  CLASS based implementation.                                              *)\r
+(*  Use TGnuGettextInstance to have more than one language                   *)\r
+(*  in your application at the same time                                     *)\r
+(*                                                                           *)\r
+(*****************************************************************************)\r
+\r
+{$ifdef MSWINDOWS}\r
+{$ifndef DELPHI6OROLDER}\r
+{$WARN UNSAFE_TYPE OFF}\r
+{$WARN UNSAFE_CODE OFF}\r
+{$WARN UNSAFE_CAST OFF}\r
+{$endif}\r
+{$endif}\r
+\r
+type\r
+  TOnDebugLine = Procedure (Sender: TObject; const Line: String; var Discard: Boolean) of Object;  // Set Discard to false if output should still go to ordinary debug log\r
+  TGetPluralForm=function (Number:Longint):Integer;\r
+  TDebugLogger=procedure (line: ansistring) of object;\r
+  TMoFile= // Don't use this class. It's for internal use.\r
+    class // Threadsafe. Only constructor and destructor are writing to memory\r
+    private\r
+      doswap: boolean;\r
+    public\r
+      Users:Integer; // Reference count. If it reaches zero, this object should be destroyed.\r
+      constructor Create (filename:string;Offset,Size:int64);\r
+      destructor Destroy; override;\r
+      function gettext(const msgid: ansistring;var found:boolean): ansistring; // uses mo file\r
+      property isSwappedArchitecture:boolean read doswap;\r
+    private\r
+      N, O, T: Cardinal; // Values defined at http://www.linuxselfhelp.com/gnu/gettext/html_chapter/gettext_6.html\r
+      startindex,startstep:integer;\r
+      {$ifdef mswindows}\r
+      mo: THandle;\r
+      momapping: THandle;\r
+      {$endif}\r
+      momemoryHandle:PChar;\r
+      momemory: PChar;\r
+      function autoswap32(i: cardinal): cardinal;\r
+      function CardinalInMem(baseptr: PChar; Offset: Cardinal): Cardinal;\r
+    end;\r
+  TDomain= // Don't use this class. It's for internal use.\r
+    class\r
+    private\r
+      Enabled:boolean;\r
+      vDirectory: string;\r
+      procedure setDirectory(const dir: string);\r
+    public\r
+      DebugLogger:TDebugLogger;\r
+      Domain: string;\r
+      property Directory: string read vDirectory write setDirectory;\r
+      constructor Create;\r
+      destructor Destroy; override;\r
+      // Set parameters\r
+      procedure SetLanguageCode (const langcode:string);\r
+      procedure SetFilename (const filename:string); // Bind this domain to a specific file\r
+      // Get information\r
+      procedure GetListOfLanguages(list:TStrings);\r
+      function GetTranslationProperty(Propertyname: string): WideString;\r
+      function gettext(const msgid: ansistring): ansistring; // uses mo file\r
+    private\r
+      mofile:TMoFile;\r
+      SpecificFilename:string;\r
+      curlang: string;\r
+      OpenHasFailedBefore: boolean;\r
+      procedure OpenMoFile;\r
+      procedure CloseMoFile;\r
+    end;\r
+  TExecutable=\r
+    class\r
+      procedure Execute; virtual; abstract;\r
+    end;\r
+  TGnuGettextInstance=\r
+    class\r
+    private\r
+      fOnDebugLine:TOnDebugLine;\r
+      CreatorThread:Cardinal;  // Only this thread can use LoadResString\r
+    public\r
+      Enabled:Boolean;      // Set this to false to disable translations\r
+      DesignTimeCodePage:Integer;  // See MultiByteToWideChar() in Win32 API for documentation\r
+      constructor Create;\r
+      destructor Destroy; override;\r
+      procedure UseLanguage(LanguageCode: string);\r
+      procedure GetListOfLanguages (const domain:string; list:TStrings); // Puts list of language codes, for which there are translations in the specified domain, into list\r
+      {$ifdef DELPHI5OROLDER}\r
+      function gettext(const szMsgId: widestring): widestring;\r
+      function ngettext(const singular,plural:widestring;Number:longint):widestring;\r
+      {$endif}\r
+      {$ifndef DELPHI5OROLDER}\r
+      function gettext(const szMsgId: ansistring): widestring; overload;\r
+      function gettext(const szMsgId: widestring): widestring; overload;\r
+      function ngettext(const singular,plural:ansistring;Number:longint):widestring; overload;\r
+      function ngettext(const singular,plural:widestring;Number:longint):widestring; overload;\r
+      {$endif}\r
+      function GetCurrentLanguage:string;\r
+      function GetTranslationProperty (const Propertyname:string):WideString;\r
+      function GetTranslatorNameAndEmail:widestring;\r
+\r
+      // Form translation tools, these are not threadsafe. All TP_ procs must be called just before TranslateProperites()\r
+      procedure TP_Ignore(AnObject:TObject; const name:string);\r
+      procedure TP_IgnoreClass (IgnClass:TClass);\r
+      procedure TP_IgnoreClassProperty (IgnClass:TClass;propertyname:string);\r
+      procedure TP_GlobalIgnoreClass (IgnClass:TClass);\r
+      procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;propertyname:string);\r
+      procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator);\r
+      procedure TranslateProperties(AnObject: TObject; textdomain:string='');\r
+      procedure TranslateComponent(AnObject: TComponent; const TextDomain:string='');\r
+      procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string='');\r
+\r
+      // Multi-domain functions\r
+      {$ifdef DELPHI5OROLDER}\r
+      function dgettext(const szDomain: string; const szMsgId: widestring): widestring;\r
+      function dngettext(const szDomain: string; const singular,plural:widestring;Number:longint):widestring;\r
+      {$endif}\r
+      {$ifndef DELPHI5OROLDER}\r
+      function dgettext(const szDomain: string; const szMsgId: ansistring): widestring; overload;\r
+      function dgettext(const szDomain: string; const szMsgId: widestring): widestring; overload;\r
+      function dngettext(const szDomain: string; const singular,plural:ansistring;Number:longint):widestring; overload;\r
+      function dngettext(const szDomain: string; const singular,plural:widestring;Number:longint):widestring; overload;\r
+      {$endif}\r
+      procedure textdomain(const szDomain: string);\r
+      function getcurrenttextdomain: string;\r
+      procedure bindtextdomain(const szDomain: string; const szDirectory: string);\r
+      procedure bindtextdomainToFile (const szDomain: string; const filename: string); // Also works with files embedded in exe file\r
+\r
+      // Windows API functions\r
+      function LoadResString(ResStringRec: PResStringRec): widestring;\r
+\r
+      // Output all log info to this file. This may only be called once.\r
+      procedure DebugLogToFile (const filename:string; append:boolean=false);\r
+      procedure DebugLogPause (PauseEnabled:boolean);\r
+      property  OnDebugLine: TOnDebugLine read fOnDebugLine write fOnDebugLine; // If set, all debug output goes here\r
+\r
+      // Conversion according to design-time character set\r
+      function ansi2wide (const s:ansistring):widestring;\r
+    protected\r
+      procedure TranslateStrings (sl:TStrings;const TextDomain:string);\r
+\r
+      // Override these three, if you want to inherited from this class\r
+      // to create a new class that handles other domain and language dependent\r
+      // issues\r
+      procedure WhenNewLanguage (const LanguageID:string); virtual;         // Override to know when language changes\r
+      procedure WhenNewDomain (const TextDomain:string); virtual; // Override to know when text domain changes. Directory is purely informational\r
+      procedure WhenNewDomainDirectory (const TextDomain,Directory:string); virtual; // Override to know when any text domain's directory changes. It won't be called if a domain is fixed to a specific file.\r
+    private\r
+      curlang: string;\r
+      curGetPluralForm:TGetPluralForm;\r
+      curmsgdomain: string;\r
+      savefileCS: TMultiReadExclusiveWriteSynchronizer;\r
+      savefile: TextFile;\r
+      savememory: TStringList;\r
+      DefaultDomainDirectory:string;\r
+      domainlist: TStringList;     // List of domain names. Objects are TDomain.\r
+      TP_IgnoreList:TStringList;   // Temporary list, reset each time TranslateProperties is called\r
+      TP_ClassHandling:TList;      // Items are TClassMode. If a is derived from b, a comes first\r
+      TP_GlobalClassHandling:TList;      // Items are TClassMode. If a is derived from b, a comes first\r
+      TP_Retranslator:TExecutable; // Cast this to TTP_Retranslator\r
+      DebugLogCS:TMultiReadExclusiveWriteSynchronizer;\r
+      DebugLog:TStream;\r
+      DebugLogOutputPaused:Boolean;\r
+      function TP_CreateRetranslator:TExecutable;  // Must be freed by caller!\r
+      procedure FreeTP_ClassHandlingItems;\r
+      procedure DebugWriteln(line: ansistring);\r
+      procedure TranslateProperty(AnObject: TObject; PropInfo: PPropInfo;\r
+        TodoList: TStrings; const TextDomain:string);\r
+      function Getdomain(const domain, DefaultDomainDirectory, CurLang: string): TDomain;  // Translates a single property of an object\r
+    end;\r
+\r
+var\r
+  DefaultInstance:TGnuGettextInstance;\r
+\r
+// DELPHI 4\r
+\r
+function GetStrProp(Instance: TObject; const Name: string): string; overload;\r
+function GetStrProp(Instance: TObject; Info: PPropInfo): string; overload;\r
+\r
+procedure SetStrProp(Instance: TObject; const Name, Value: string); overload;\r
+procedure SetStrProp(Instance: TObject; Info: PPropInfo; const Value: string); overload;\r
+\r
+implementation\r
+\r
+(**************************************************************************)\r
+// Some comments on the implementation:\r
+// This unit should be independent of other units where possible.\r
+// It should have a small footprint in any way.\r
+(**************************************************************************)\r
+// TMultiReadExclusiveWriteSynchronizer is used instead of TCriticalSection\r
+// because it makes this unit independent of the SyncObjs unit\r
+(**************************************************************************)\r
+\r
+{$ifdef DELPHI5OROLDER}\r
+uses\r
+  FileCtrl;\r
+{$endif}\r
+\r
+type\r
+  TTP_RetranslatorItem=\r
+    class\r
+      obj:TObject;\r
+      Propname:string;\r
+      OldValue:WideString;\r
+    end;\r
+  TTP_Retranslator=\r
+    class (TExecutable)\r
+      TextDomain:string;\r
+      Instance:TGnuGettextInstance;\r
+      constructor Create;\r
+      destructor Destroy; override;\r
+      procedure Remember (obj:TObject; PropName:String; OldValue:WideString);\r
+      procedure Execute; override;\r
+    private\r
+      list:TList;\r
+    end;\r
+  TEmbeddedFileInfo=\r
+    class\r
+      offset,size:int64;\r
+    end;\r
+  TFileLocator=\r
+    class // This class finds files even when embedded inside executable\r
+      constructor Create;\r
+      destructor Destroy; override;\r
+      procedure Analyze;  // List files embedded inside executable\r
+      function FileExists (filename:string):boolean;\r
+      function GetMoFile (filename:string;DebugLogger:TDebugLogger):TMoFile;\r
+      procedure ReleaseMoFile (mofile:TMoFile);\r
+    private\r
+      basedirectory:string;\r
+      filelist:TStringList; //Objects are TEmbeddedFileInfo. Filenames are relative to .exe file\r
+      MoFilesCS:TMultiReadExclusiveWriteSynchronizer;\r
+      MoFiles:TStringList; // Objects are filenames+offset, objects are TMoFile\r
+      function ReadInt64 (str:TStream):int64;\r
+    end;\r
+  TGnuGettextComponentMarker=\r
+    class (TComponent)\r
+    public\r
+      LastLanguage:string;\r
+      Retranslator:TExecutable;\r
+      destructor Destroy; override;\r
+    end;\r
+  TClassMode=\r
+    class\r
+      HClass:TClass;\r
+      SpecialHandler:TTranslator;\r
+      PropertiesToIgnore:TStringList; // This is ignored if Handler is set\r
+      constructor Create;\r
+      destructor Destroy; override;\r
+    end;\r
+  TRStrinfo = record\r
+    strlength, stroffset: cardinal;\r
+  end;\r
+  TStrInfoArr = array[0..10000000] of TRStrinfo;\r
+  PStrInfoArr = ^TStrInfoArr;\r
+  TCharArray5=array[0..4] of ansichar;\r
+  THook=  // Replaces a runtime library procedure with a custom procedure\r
+    class\r
+    public\r
+      constructor Create (OldProcedure, NewProcedure: pointer; FollowJump:boolean=false);\r
+      destructor Destroy; override;  // Restores unhooked state\r
+      procedure Reset (FollowJump:boolean=false); // Disables and picks up patch points again\r
+      procedure Disable;\r
+      procedure Enable;\r
+    private\r
+      oldproc,newproc:Pointer;\r
+      Patch:TCharArray5;\r
+      Original:TCharArray5;\r
+      PatchPosition:PChar;\r
+      procedure Shutdown; // Same as destroy, except that object is not destroyed\r
+    end;\r
+\r
+var\r
+  // System information\r
+  Win32PlatformIsUnicode:boolean=False;\r
+  \r
+  // Information about files embedded inside .exe file\r
+  FileLocator:TFileLocator;\r
+\r
+  // Hooks into runtime library functions\r
+  ResourceStringDomainListCS:TMultiReadExclusiveWriteSynchronizer;\r
+  ResourceStringDomainList:TStringList;\r
+  HookLoadResString:THook;\r
+  HookLoadStr:THook;\r
+  HookFmtLoadStr:THook;\r
+\r
+function GGGetEnvironmentVariable(const Name:string):string;\r
+var\r
+  Len: integer;\r
+  W : String;\r
+begin\r
+  Result := '';\r
+  SetLength(W,1);\r
+  Len := Windows.GetEnvironmentVariable(PChar(Name), PChar(W), 1);\r
+  if Len > 0 then begin\r
+    SetLength(Result, Len - 1);\r
+    Windows.GetEnvironmentVariable(PChar(Name), PChar(Result), Len);\r
+  end;\r
+end;\r
+\r
+function StripCR (s:string):string;\r
+var\r
+  i:integer;\r
+begin\r
+  i:=1;\r
+  while i<=length(s) do begin\r
+    if s[i]=#13 then delete (s,i,1) else inc (i);\r
+  end;\r
+  Result:=s;\r
+end;\r
+\r
+function LF2LineBreakA (s:string):string;\r
+{$ifdef MSWINDOWS}\r
+var\r
+  i:integer;\r
+{$endif}\r
+begin\r
+  {$ifdef MSWINDOWS}\r
+  Assert (sLinebreak=#13#10);\r
+  i:=1;\r
+  while i<=length(s) do begin\r
+    if (s[i]=#10) and (copy(s,i-1,1)<>#13) then begin\r
+      insert (#13,s,i);\r
+      inc (i,2);\r
+    end else\r
+      inc (i);\r
+  end;\r
+  {$endif}\r
+  Result:=s;\r
+end;\r
+\r
+function IsWriteProp(Info: PPropInfo): Boolean;\r
+begin\r
+  Result := Assigned(Info) and (Info^.SetProc <> nil);\r
+end;\r
+\r
+function string2csyntax(s: string): string;\r
+// Converts a string to the syntax that is used in .po files\r
+var\r
+  i: integer;\r
+  c: char;\r
+begin\r
+  Result := '';\r
+  for i := 1 to length(s) do begin\r
+    c := s[i];\r
+    case c of\r
+      #32..#33, #35..#255: Result := Result + c;\r
+      #13: Result := Result + '\r';\r
+      #10: Result := Result + '\n"'#13#10'"';\r
+      #34: Result := Result + '\"';\r
+    else\r
+      Result := Result + '\0x' + IntToHex(ord(c), 2);\r
+    end;\r
+  end;\r
+  Result := '"' + Result + '"';\r
+end;\r
+\r
+function ResourceStringGettext(MsgId: widestring): widestring;\r
+var\r
+  i:integer;\r
+begin\r
+  if (MsgID='') or (ResourceStringDomainListCS=nil) then begin\r
+    // This only happens during very complicated program startups that fail,\r
+    // or when Msgid=''\r
+    Result:=MsgId;\r
+    exit;\r
+  end;\r
+  ResourceStringDomainListCS.BeginRead;\r
+  try\r
+    for i:=0 to ResourceStringDomainList.Count-1 do begin\r
+      Result:=dgettext(ResourceStringDomainList.Strings[i], MsgId);\r
+      if Result<>MsgId then\r
+        break;\r
+    end;\r
+  finally\r
+    ResourceStringDomainListCS.EndRead;\r
+  end;\r
+end;\r
+\r
+function gettext(const szMsgId: widestring): widestring;\r
+begin\r
+  Result:=DefaultInstance.gettext(szMsgId);\r
+end;\r
+\r
+function _(const szMsgId: widestring): widestring;\r
+begin\r
+  Result:=DefaultInstance.gettext(szMsgId);\r
+end;\r
+\r
+function dgettext(const szDomain: string; const szMsgId: widestring): widestring;\r
+begin\r
+  Result:=DefaultInstance.dgettext(szDomain, szMsgId);\r
+end;\r
+\r
+function dngettext(const szDomain: string; const singular,plural: widestring; Number:longint): widestring;\r
+begin\r
+  Result:=DefaultInstance.dngettext(szDomain,singular,plural,Number);\r
+end;\r
+\r
+function ngettext(const singular,plural: widestring; Number:longint): widestring;\r
+begin\r
+  Result:=DefaultInstance.ngettext(singular,plural,Number);\r
+end;\r
+\r
+procedure textdomain(const szDomain: string);\r
+begin\r
+  DefaultInstance.textdomain(szDomain);\r
+end;\r
+\r
+procedure SetGettextEnabled (enabled:boolean);\r
+begin\r
+  DefaultInstance.Enabled:=enabled;\r
+end;\r
+\r
+function getcurrenttextdomain: string;\r
+begin\r
+  Result:=DefaultInstance.getcurrenttextdomain;\r
+end;\r
+\r
+procedure bindtextdomain(const szDomain: string; const szDirectory: string);\r
+begin\r
+  DefaultInstance.bindtextdomain(szDomain, szDirectory);\r
+end;\r
+\r
+procedure TP_Ignore(AnObject:TObject; const name:string);\r
+begin\r
+  DefaultInstance.TP_Ignore(AnObject, name);\r
+end;\r
+\r
+procedure TP_GlobalIgnoreClass (IgnClass:TClass);\r
+begin\r
+  DefaultInstance.TP_GlobalIgnoreClass(IgnClass);\r
+end;\r
+\r
+procedure TP_IgnoreClass (IgnClass:TClass);\r
+begin\r
+  DefaultInstance.TP_IgnoreClass(IgnClass);\r
+end;\r
+\r
+procedure TP_IgnoreClassProperty (IgnClass:TClass;const propertyname:string);\r
+begin\r
+  DefaultInstance.TP_IgnoreClassProperty(IgnClass,propertyname);\r
+end;\r
+\r
+procedure TP_GlobalIgnoreClassProperty (IgnClass:TClass;const propertyname:string);\r
+begin\r
+  DefaultInstance.TP_GlobalIgnoreClassProperty(IgnClass,propertyname);\r
+end;\r
+\r
+procedure TP_GlobalHandleClass (HClass:TClass;Handler:TTranslator);\r
+begin\r
+  DefaultInstance.TP_GlobalHandleClass (HClass, Handler);\r
+end;\r
+\r
+procedure TranslateComponent(AnObject: TComponent; const TextDomain:string='');\r
+begin\r
+  DefaultInstance.TranslateComponent(AnObject, TextDomain);\r
+end;\r
+\r
+procedure RetranslateComponent(AnObject: TComponent; const TextDomain:string='');\r
+begin\r
+  DefaultInstance.RetranslateComponent(AnObject, TextDomain);\r
+end;\r
+\r
+{$ifdef MSWINDOWS}\r
+\r
+// These constants are only used in Windows 95\r
+// Thanks to Frank Andreas de Groot for this table\r
+const\r
+  IDAfrikaans                 = $0436;  IDAlbanian                  = $041C;\r
+  IDArabicAlgeria             = $1401;  IDArabicBahrain             = $3C01;\r
+  IDArabicEgypt               = $0C01;  IDArabicIraq                = $0801;\r
+  IDArabicJordan              = $2C01;  IDArabicKuwait              = $3401;\r
+  IDArabicLebanon             = $3001;  IDArabicLibya               = $1001;\r
+  IDArabicMorocco             = $1801;  IDArabicOman                = $2001;\r
+  IDArabicQatar               = $4001;  IDArabic                    = $0401;\r
+  IDArabicSyria               = $2801;  IDArabicTunisia             = $1C01;\r
+  IDArabicUAE                 = $3801;  IDArabicYemen               = $2401;\r
+  IDArmenian                  = $042B;  IDAssamese                  = $044D;\r
+  IDAzeriCyrillic             = $082C;  IDAzeriLatin                = $042C;\r
+  IDBasque                    = $042D;  IDByelorussian              = $0423;\r
+  IDBengali                   = $0445;  IDBulgarian                 = $0402;\r
+  IDBurmese                   = $0455;  IDCatalan                   = $0403;\r
+  IDChineseHongKong           = $0C04;  IDChineseMacao              = $1404;\r
+  IDSimplifiedChinese         = $0804;  IDChineseSingapore          = $1004;\r
+  IDTraditionalChinese        = $0404;  IDCroatian                  = $041A;\r
+  IDCzech                     = $0405;  IDDanish                    = $0406;\r
+  IDBelgianDutch              = $0813;  IDDutch                     = $0413;\r
+  IDEnglishAUS                = $0C09;  IDEnglishBelize             = $2809;\r
+  IDEnglishCanadian           = $1009;  IDEnglishCaribbean          = $2409;\r
+  IDEnglishIreland            = $1809;  IDEnglishJamaica            = $2009;\r
+  IDEnglishNewZealand         = $1409;  IDEnglishPhilippines        = $3409;\r
+  IDEnglishSouthAfrica        = $1C09;  IDEnglishTrinidad           = $2C09;\r
+  IDEnglishUK                 = $0809;  IDEnglishUS                 = $0409;\r
+  IDEnglishZimbabwe           = $3009;  IDEstonian                  = $0425;\r
+  IDFaeroese                  = $0438;  IDFarsi                     = $0429;\r
+  IDFinnish                   = $040B;  IDBelgianFrench             = $080C;\r
+  IDFrenchCameroon            = $2C0C;  IDFrenchCanadian            = $0C0C;\r
+  IDFrenchCotedIvoire         = $300C;  IDFrench                    = $040C;\r
+  IDFrenchLuxembourg          = $140C;  IDFrenchMali                = $340C;\r
+  IDFrenchMonaco              = $180C;  IDFrenchReunion             = $200C;\r
+  IDFrenchSenegal             = $280C;  IDSwissFrench               = $100C;\r
+  IDFrenchWestIndies          = $1C0C;  IDFrenchZaire               = $240C;\r
+  IDFrisianNetherlands        = $0462;  IDGaelicIreland             = $083C;\r
+  IDGaelicScotland            = $043C;  IDGalician                  = $0456;\r
+  IDGeorgian                  = $0437;  IDGermanAustria             = $0C07;\r
+  IDGerman                    = $0407;  IDGermanLiechtenstein       = $1407;\r
+  IDGermanLuxembourg          = $1007;  IDSwissGerman               = $0807;\r
+  IDGreek                     = $0408;  IDGujarati                  = $0447;\r
+  IDHebrew                    = $040D;  IDHindi                     = $0439;\r
+  IDHungarian                 = $040E;  IDIcelandic                 = $040F;\r
+  IDIndonesian                = $0421;  IDItalian                   = $0410;\r
+  IDSwissItalian              = $0810;  IDJapanese                  = $0411;\r
+  IDKannada                   = $044B;  IDKashmiri                  = $0460;\r
+  IDKazakh                    = $043F;  IDKhmer                     = $0453;\r
+  IDKirghiz                   = $0440;  IDKonkani                   = $0457;\r
+  IDKorean                    = $0412;  IDLao                       = $0454;\r
+  IDLatvian                   = $0426;  IDLithuanian                = $0427;\r
+  IDMacedonian                = $042F;  IDMalaysian                 = $043E;\r
+  IDMalayBruneiDarussalam     = $083E;  IDMalayalam                 = $044C;\r
+  IDMaltese                   = $043A;  IDManipuri                  = $0458;\r
+  IDMarathi                   = $044E;  IDMongolian                 = $0450;\r
+  IDNepali                    = $0461;  IDNorwegianBokmol           = $0414;\r
+  IDNorwegianNynorsk          = $0814;  IDOriya                     = $0448;\r
+  IDPolish                    = $0415;  IDBrazilianPortuguese       = $0416;\r
+  IDPortuguese                = $0816;  IDPunjabi                   = $0446;\r
+  IDRhaetoRomanic             = $0417;  IDRomanianMoldova           = $0818;\r
+  IDRomanian                  = $0418;  IDRussianMoldova            = $0819;\r
+  IDRussian                   = $0419;  IDSamiLappish               = $043B;\r
+  IDSanskrit                  = $044F;  IDSerbianCyrillic           = $0C1A;\r
+  IDSerbianLatin              = $081A;  IDSesotho                   = $0430;\r
+  IDSindhi                    = $0459;  IDSlovak                    = $041B;\r
+  IDSlovenian                 = $0424;  IDSorbian                   = $042E;\r
+  IDSpanishArgentina          = $2C0A;  IDSpanishBolivia            = $400A;\r
+  IDSpanishChile              = $340A;  IDSpanishColombia           = $240A;\r
+  IDSpanishCostaRica          = $140A;  IDSpanishDominicanRepublic  = $1C0A;\r
+  IDSpanishEcuador            = $300A;  IDSpanishElSalvador         = $440A;\r
+  IDSpanishGuatemala          = $100A;  IDSpanishHonduras           = $480A;\r
+  IDMexicanSpanish            = $080A;  IDSpanishNicaragua          = $4C0A;\r
+  IDSpanishPanama             = $180A;  IDSpanishParaguay           = $3C0A;\r
+  IDSpanishPeru               = $280A;  IDSpanishPuertoRico         = $500A;\r
+  IDSpanishModernSort         = $0C0A;  IDSpanish                   = $040A;\r
+  IDSpanishUruguay            = $380A;  IDSpanishVenezuela          = $200A;\r
+  IDSutu                      = $0430;  IDSwahili                   = $0441;\r
+  IDSwedishFinland            = $081D;  IDSwedish                   = $041D;\r
+  IDTajik                     = $0428;  IDTamil                     = $0449;\r
+  IDTatar                     = $0444;  IDTelugu                    = $044A;\r
+  IDThai                      = $041E;  IDTibetan                   = $0451;\r
+  IDTsonga                    = $0431;  IDTswana                    = $0432;\r
+  IDTurkish                   = $041F;  IDTurkmen                   = $0442;\r
+  IDUkrainian                 = $0422;  IDUrdu                      = $0420;\r
+  IDUzbekCyrillic             = $0843;  IDUzbekLatin                = $0443;\r
+  IDVenda                     = $0433;  IDVietnamese                = $042A;\r
+  IDWelsh                     = $0452;  IDXhosa                     = $0434;\r
+  IDZulu                      = $0435;\r
+\r
+function GetWindowsLanguage: string;\r
+var\r
+  langid: Cardinal;\r
+  langcode: string;\r
+  CountryName: array[0..4] of char;\r
+  LanguageName: array[0..4] of char;\r
+  works: boolean;\r
+begin\r
+  // The return value of GetLocaleInfo is compared with 3 = 2 characters and a zero\r
+  works := 3 = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, LanguageName, SizeOf(LanguageName));\r
+  works := works and (3 = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, CountryName,\r
+    SizeOf(CountryName)));\r
+  if works then begin\r
+    // Windows 98, Me, NT4, 2000, XP and newer\r
+    LangCode := PChar(@LanguageName[0]);\r
+    if lowercase(LangCode)='no' then LangCode:='nb';\r
+    LangCode:=LangCode + '_' + PChar(@CountryName[0]);\r
+  end else begin\r
+    // This part should only happen on Windows 95.\r
+    langid := GetThreadLocale;\r
+    case langid of\r
+      IDBelgianDutch: langcode := 'nl_BE';\r
+      IDBelgianFrench: langcode := 'fr_BE';\r
+      IDBrazilianPortuguese: langcode := 'pt_BR';\r
+      IDDanish: langcode := 'da_DK';\r
+      IDDutch: langcode := 'nl_NL';\r
+      IDEnglishUK: langcode := 'en_GB';\r
+      IDEnglishUS: langcode := 'en_US';\r
+      IDFinnish: langcode := 'fi_FI';\r
+      IDFrench: langcode := 'fr_FR';\r
+      IDFrenchCanadian: langcode := 'fr_CA';\r
+      IDGerman: langcode := 'de_DE';\r
+      IDGermanLuxembourg: langcode := 'de_LU';\r
+      IDGreek: langcode := 'el_GR';\r
+      IDIcelandic: langcode := 'is_IS';\r
+      IDItalian: langcode := 'it_IT';\r
+      IDKorean: langcode := 'ko_KO';\r
+      IDNorwegianBokmol: langcode := 'nb_NO';\r
+      IDNorwegianNynorsk: langcode := 'nn_NO';\r
+      IDPolish: langcode := 'pl_PL';\r
+      IDPortuguese: langcode := 'pt_PT';\r
+      IDRussian: langcode := 'ru_RU';\r
+      IDSpanish, IDSpanishModernSort: langcode := 'es_ES';\r
+      IDSwedish: langcode := 'sv_SE';\r
+      IDSwedishFinland: langcode := 'sv_FI';\r
+    else\r
+      langcode := 'C';\r
+    end;\r
+  end;\r
+  Result := langcode;\r
+end;\r
+{$endif}\r
+\r
+function LoadResStringA(ResStringRec: PResStringRec): string;\r
+begin\r
+  Result:=DefaultInstance.LoadResString(ResStringRec);\r
+end;\r
+\r
+function GetTranslatorNameAndEmail:widestring;\r
+begin\r
+  Result:=DefaultInstance.GetTranslatorNameAndEmail;\r
+end;\r
+\r
+procedure UseLanguage(LanguageCode: string);\r
+begin\r
+  DefaultInstance.UseLanguage(LanguageCode);\r
+end;\r
+\r
+type\r
+  PStrData = ^TStrData;\r
+  TStrData = record\r
+    Ident: Integer;\r
+    Str: string;\r
+  end;\r
+  \r
+function SysUtilsEnumStringModules(Instance: Longint; Data: Pointer): Boolean;\r
+{$IFDEF MSWINDOWS}\r
+var\r
+  Buffer: array [0..1023] of char;\r
+begin\r
+  with PStrData(Data)^ do begin\r
+    SetString(Str, Buffer,\r
+      LoadString(Instance, Ident, Buffer, sizeof(Buffer)));\r
+    Result := Str = '';\r
+  end;\r
+end;\r
+{$ENDIF}\r
+{$IFDEF LINUX}\r
+var\r
+  rs:TResStringRec;\r
+  Module:HModule;\r
+begin\r
+  Module:=Instance;\r
+  rs.Module:=@Module;\r
+  with PStrData(Data)^ do begin\r
+    rs.Identifier:=Ident;\r
+    Str:=System.LoadResString(@rs);\r
+    Result:=Str='';\r
+  end;\r
+end;\r
+{$ENDIF}\r
+\r
+function SysUtilsFindStringResource(Ident: Integer): string;\r
+var\r
+  StrData: TStrData;\r
+begin\r
+  StrData.Ident := Ident;\r
+  StrData.Str := '';\r
+  EnumResourceModules(SysUtilsEnumStringModules, @StrData);\r
+  Result := StrData.Str;\r
+end;\r
+\r
+function SysUtilsLoadStr(Ident: Integer): string;\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DefaultInstance.DebugWriteln ('Sysutils.LoadRes('+IntToStr(ident)+') called');\r
+  {$endif}\r
+  Result := ResourceStringGettext(SysUtilsFindStringResource(Ident));\r
+end;\r
+\r
+function SysUtilsFmtLoadStr(Ident: Integer; const Args: array of const): string;\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DefaultInstance.DebugWriteln ('Sysutils.FmtLoadRes('+IntToStr(ident)+',Args) called');\r
+  {$endif}\r
+  FmtStr(Result, SysUtilsFindStringResource(Ident), Args);\r
+  Result:=ResourceStringGettext(Result);\r
+end;\r
+\r
+function LoadResString(ResStringRec: PResStringRec): widestring;\r
+begin\r
+  Result:=DefaultInstance.LoadResString(ResStringRec);\r
+end;\r
+\r
+function LoadResStringW(ResStringRec: PResStringRec): widestring;\r
+begin\r
+  Result:=DefaultInstance.LoadResString(ResStringRec);\r
+end;\r
+\r
+\r
+\r
+function GetCurrentLanguage:string;\r
+begin\r
+  Result:=DefaultInstance.GetCurrentLanguage;\r
+end;\r
+\r
+{ TDomain }\r
+\r
+procedure TDomain.CloseMoFile;\r
+begin\r
+  if mofile<>nil then begin\r
+    FileLocator.ReleaseMoFile(mofile);\r
+    mofile:=nil;\r
+  end;\r
+  OpenHasFailedBefore:=False;\r
+end;\r
+\r
+destructor TDomain.Destroy;\r
+begin\r
+  CloseMoFile;\r
+  inherited;\r
+end;\r
+\r
+{$ifdef mswindows}\r
+function GetLastWinError:string;\r
+var\r
+  errcode:Cardinal;\r
+begin\r
+  SetLength (Result,2000);\r
+  errcode:=GetLastError();\r
+  Windows.FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,errcode,0,PChar(Result),2000,nil);\r
+  Result:=StrPas(PChar(Result));\r
+end;\r
+{$endif}\r
+\r
+procedure TDomain.OpenMoFile;\r
+var\r
+  filename: string;\r
+begin\r
+  // Check if it is already open\r
+  if mofile<>nil then\r
+    exit;\r
+\r
+  // Check if it has been attempted to open the file before\r
+  if OpenHasFailedBefore then\r
+    exit;\r
+\r
+  if SpecificFilename<>'' then\r
+    filename:=SpecificFilename\r
+  else begin\r
+    filename := Directory + curlang + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo';\r
+    if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then\r
+      filename := Directory + copy(curlang, 1, 2) + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo';\r
+  end;\r
+  if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then begin\r
+    OpenHasFailedBefore:=True;\r
+    exit;\r
+  end;\r
+  mofile:=FileLocator.GetMoFile(filename, DebugLogger);\r
+\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  if mofile.isSwappedArchitecture then\r
+    DebugLogger ('.mo file is swapped (comes from another CPU architecture)');\r
+  {$endif}\r
+\r
+  // Check, that the contents of the file is utf-8\r
+  if pos('CHARSET=UTF-8',uppercase(GetTranslationProperty('Content-Type')))=0 then begin\r
+    CloseMoFile;\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugLogger ('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.');\r
+    {$endif}\r
+    {$ifdef MSWINDOWS}\r
+    MessageBox(0,PChar('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'),'Localization problem',MB_OK);\r
+    {$else}\r
+    writeln (stderr,'The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.');\r
+    {$endif}\r
+    Enabled:=False;\r
+  end;\r
+end;\r
+\r
+function TDomain.GetTranslationProperty(\r
+  Propertyname: string): WideString;\r
+var\r
+  sl:TStringList;\r
+  i:integer;\r
+  s:string;\r
+begin\r
+  Propertyname:=uppercase(Propertyname)+': ';\r
+  sl:=TStringList.Create;\r
+  try\r
+    sl.Text:=utf8encode(gettext(''));\r
+    for i:=0 to sl.Count-1 do begin\r
+      s:=sl.Strings[i];\r
+      if uppercase(copy(s,1,length(Propertyname)))=Propertyname then begin\r
+        Result:=utf8decode(trim(copy(s,length(PropertyName)+1,maxint)));\r
+        {$ifdef DXGETTEXTDEBUG}\r
+        DebugLogger ('GetTranslationProperty('+PropertyName+') returns '''+Result+'''.');\r
+        {$endif}\r
+        exit;\r
+      end;\r
+    end;\r
+  finally\r
+    FreeAndNil (sl);\r
+  end;\r
+  Result:='';\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugLogger ('GetTranslationProperty('+PropertyName+') did not find any value. An empty string is returned.');\r
+  {$endif}\r
+end;\r
+\r
+procedure TDomain.setDirectory(const dir: string);\r
+begin\r
+  vDirectory := IncludeTrailingPathDelimiter(dir);\r
+  SpecificFilename:='';\r
+  CloseMoFile;\r
+end;\r
+\r
+procedure AddDomainForResourceString (const domain:string);\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DefaultInstance.DebugWriteln ('Extra domain for resourcestring: '+domain);\r
+  {$endif}\r
+  ResourceStringDomainListCS.BeginWrite;\r
+  try\r
+    if ResourceStringDomainList.IndexOf(domain)=-1 then\r
+      ResourceStringDomainList.Add (domain);\r
+  finally\r
+    ResourceStringDomainListCS.EndWrite;\r
+  end;\r
+end;\r
+\r
+procedure RemoveDomainForResourceString (const domain:string);\r
+var\r
+  i:integer;\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DefaultInstance.DebugWriteln ('Remove domain for resourcestring: '+domain);\r
+  {$endif}\r
+  ResourceStringDomainListCS.BeginWrite;\r
+  try\r
+    i:=ResourceStringDomainList.IndexOf(domain);\r
+    if i<>-1 then\r
+      ResourceStringDomainList.Delete (i);\r
+  finally\r
+    ResourceStringDomainListCS.EndWrite;\r
+  end;\r
+end;\r
+\r
+procedure TDomain.SetLanguageCode(const langcode: string);\r
+begin\r
+  CloseMoFile;\r
+  curlang:=langcode;\r
+end;\r
+\r
+function GetPluralForm2EN(Number: Integer): Integer;\r
+begin\r
+  Number:=abs(Number);\r
+  if Number=1 then Result:=0 else Result:=1;\r
+end;\r
+\r
+function GetPluralForm1(Number: Integer): Integer;\r
+begin\r
+  Result:=0;\r
+end;\r
+\r
+function GetPluralForm2FR(Number: Integer): Integer;\r
+begin\r
+  Number:=abs(Number);\r
+  if (Number=1) or (Number=0) then Result:=0 else Result:=1;\r
+end;\r
+\r
+function GetPluralForm3LV(Number: Integer): Integer;\r
+begin\r
+  Number:=abs(Number);\r
+  if (Number mod 10=1) and (Number mod 100<>11) then\r
+    Result:=0\r
+  else\r
+    if Number<>0 then Result:=1\r
+                 else Result:=2;\r
+end;\r
+\r
+function GetPluralForm3GA(Number: Integer): Integer;\r
+begin\r
+  Number:=abs(Number);\r
+  if Number=1 then Result:=0\r
+  else if Number=2 then Result:=1\r
+  else Result:=2;\r
+end;\r
+\r
+function GetPluralForm3LT(Number: Integer): Integer;\r
+var\r
+  n1,n2:byte;\r
+begin\r
+  Number:=abs(Number);\r
+  n1:=Number mod 10;\r
+  n2:=Number mod 100;\r
+  if (n1=1) and (n2<>11) then\r
+    Result:=0\r
+  else\r
+    if (n1>=2) and ((n2<10) or (n2>=20)) then Result:=1\r
+    else Result:=2;\r
+end;\r
+\r
+function GetPluralForm3PL(Number: Integer): Integer;\r
+var\r
+  n1,n2:byte;\r
+begin\r
+  Number:=abs(Number);\r
+  n1:=Number mod 10;\r
+  n2:=Number mod 100;\r
+  if n1=1 then Result:=0\r
+  else if (n1>=2) and (n1<=4) and ((n2<10) or (n2>=20)) then Result:=1\r
+  else Result:=2;\r
+end;\r
+\r
+function GetPluralForm3RU(Number: Integer): Integer;\r
+var\r
+  n1,n2:byte;\r
+begin\r
+  Number:=abs(Number);\r
+  n1:=Number mod 10;\r
+  n2:=Number mod 100;\r
+  if (n1=1) and (n2<>11) then\r
+    Result:=0\r
+  else\r
+    if (n1>=2) and (n1<=4) and ((n2<10) or (n2>=20)) then Result:=1\r
+    else Result:=2;\r
+end;\r
+\r
+function GetPluralForm4SL(Number: Integer): Integer;\r
+var\r
+  n2:byte;\r
+begin\r
+  Number:=abs(Number);\r
+  n2:=Number mod 100;\r
+  if n2=1 then Result:=0\r
+  else\r
+  if n2=2 then Result:=1\r
+  else\r
+  if (n2=3) or (n2=4) then Result:=2\r
+  else\r
+    Result:=3;\r
+end;\r
+\r
+procedure TDomain.GetListOfLanguages(list: TStrings);\r
+var\r
+  sr:TSearchRec;\r
+  more:boolean;\r
+  filename, path, langcode:string;\r
+  i, j:integer;\r
+begin\r
+  list.Clear;\r
+\r
+  // Iterate through filesystem\r
+  more:=FindFirst (Directory+'*',faAnyFile,sr)=0;\r
+  while more do begin\r
+    if (sr.Attr and faDirectory<>0) and (sr.name<>'.') and (sr.name<>'..') then begin\r
+      filename := Directory + sr.Name + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo';\r
+      if fileexists(filename) then begin\r
+        langcode:=lowercase(sr.name);\r
+        if list.IndexOf(langcode)=-1 then\r
+          list.Add(langcode);\r
+      end;\r
+    end;\r
+    more:=FindNext (sr)=0;\r
+  end;\r
+\r
+  // Iterate through embedded files\r
+  for i:=0 to FileLocator.filelist.Count-1 do begin\r
+    filename:=FileLocator.basedirectory+FileLocator.filelist.Strings[i];\r
+    path:=Directory;\r
+    {$ifdef MSWINDOWS}\r
+    path:=uppercase(path);\r
+    filename:=uppercase(filename);\r
+    {$endif}\r
+    j:=length(path);\r
+    if copy(filename,1,j)=path then begin\r
+      path:=PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo';\r
+      {$ifdef MSWINDOWS}\r
+      path:=uppercase(path);\r
+      {$endif}\r
+      if copy(filename,length(filename)-length(path)+1,length(path))=path then begin\r
+        langcode:=lowercase(copy(filename,j+1,length(filename)-length(path)-j));\r
+        if list.IndexOf(langcode)=-1 then\r
+          list.Add(langcode);\r
+      end;\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TDomain.SetFilename(const filename: string);\r
+begin\r
+  CloseMoFile;\r
+  vDirectory := '';\r
+  SpecificFilename:=filename;\r
+end;\r
+\r
+function TDomain.gettext(const msgid: ansistring): ansistring;\r
+var\r
+  found:boolean;\r
+begin\r
+  if not Enabled then begin\r
+    Result:=msgid;\r
+    exit;\r
+  end;\r
+  if (mofile=nil) and (not OpenHasFailedBefore) then\r
+    OpenMoFile;\r
+  if mofile=nil then begin\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugLogger('.mo file is not open. Not translating "'+msgid+'"');\r
+    {$endif}\r
+    Result := msgid;\r
+  end else begin\r
+    Result:=mofile.gettext(msgid,found);\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    if found then\r
+      DebugLogger ('Found in .mo ('+Domain+'): "'+utf8encode(msgid)+'"->"'+utf8encode(Result)+'"')\r
+    else\r
+      DebugLogger ('Translation not found in .mo file ('+Domain+') : "'+utf8encode(msgid)+'"');\r
+    {$endif}\r
+  end;\r
+end;\r
+\r
+constructor TDomain.Create;\r
+begin\r
+  inherited Create;\r
+  Enabled:=True;\r
+end;\r
+\r
+{ TGnuGettextInstance }\r
+\r
+procedure TGnuGettextInstance.bindtextdomain(const szDomain,\r
+  szDirectory: string);\r
+var\r
+  dir:string;\r
+begin\r
+  dir:=IncludeTrailingPathDelimiter(szDirectory);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Text domain "'+szDomain+'" is now located at "'+dir+'"');\r
+  {$endif}\r
+  getdomain(szDomain,DefaultDomainDirectory,CurLang).Directory := dir;\r
+  WhenNewDomainDirectory (szDomain, szDirectory);\r
+end;\r
+\r
+constructor TGnuGettextInstance.Create;\r
+begin\r
+  CreatorThread:=GetCurrentThreadId;\r
+  {$ifdef MSWindows}\r
+  DesignTimeCodePage:=CP_ACP;\r
+  {$endif}\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugLogCS:=TMultiReadExclusiveWriteSynchronizer.Create;\r
+  DebugLog:=TMemoryStream.Create;\r
+  DebugWriteln('Debug log started '+DateTimeToStr(Now));\r
+  DebugWriteln('');\r
+  {$endif}\r
+  curGetPluralForm:=GetPluralForm2EN;\r
+  Enabled:=True;\r
+  curmsgdomain:=DefaultTextDomain;\r
+  savefileCS := TMultiReadExclusiveWriteSynchronizer.Create;\r
+  domainlist := TStringList.Create;\r
+  TP_IgnoreList:=TStringList.Create;\r
+  TP_IgnoreList.Sorted:=True;\r
+  TP_GlobalClassHandling:=TList.Create;\r
+  TP_ClassHandling:=TList.Create;\r
+\r
+  // Set some settings\r
+  DefaultDomainDirectory := IncludeTrailingPathDelimiter(extractfilepath(ExecutableFilename))+'locale';\r
+\r
+  UseLanguage('');\r
+\r
+  bindtextdomain(DefaultTextDomain, DefaultDomainDirectory);\r
+  textdomain(DefaultTextDomain);\r
+\r
+  // Add default properties to ignore\r
+  TP_GlobalIgnoreClassProperty(TComponent,'Name');\r
+  TP_GlobalIgnoreClassProperty(TCollection,'PropName');\r
+end;\r
+\r
+destructor TGnuGettextInstance.Destroy;\r
+begin\r
+  if savememory <> nil then begin\r
+    savefileCS.BeginWrite;\r
+    try\r
+      CloseFile(savefile);\r
+    finally\r
+      savefileCS.EndWrite;\r
+    end;\r
+    FreeAndNil(savememory);\r
+  end;\r
+  FreeAndNil (savefileCS);\r
+  FreeAndNil (TP_IgnoreList);\r
+  while TP_GlobalClassHandling.Count<>0 do begin\r
+    TObject(TP_GlobalClassHandling.Items[0]).Free;\r
+    TP_GlobalClassHandling.Delete(0);\r
+  end;\r
+  FreeAndNil (TP_GlobalClassHandling);\r
+  FreeTP_ClassHandlingItems;\r
+  FreeAndNil (TP_ClassHandling);\r
+  while domainlist.Count <> 0 do begin\r
+    domainlist.Objects[0].Free;\r
+    domainlist.Delete(0);\r
+  end;\r
+  FreeAndNil(domainlist);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  FreeAndNil (DebugLog);\r
+  FreeAndNil (DebugLogCS);\r
+  {$endif}\r
+  inherited;\r
+end;\r
+\r
+{$ifndef DELPHI5OROLDER}\r
+function TGnuGettextInstance.dgettext(const szDomain: string; const szMsgId: ansistring): widestring;\r
+begin\r
+  Result:=dgettext(szDomain, ansi2wide(szMsgId));\r
+end;\r
+{$endif}\r
+\r
+function TGnuGettextInstance.dgettext(const szDomain: string;\r
+  const szMsgId: widestring): widestring;\r
+begin\r
+  if not Enabled then begin\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('Translation has been disabled. Text is not being translated: '+szMsgid);\r
+    {$endif}\r
+    Result:=szMsgId;\r
+  end else begin\r
+    Result:=UTF8Decode(LF2LineBreakA(getdomain(szDomain,DefaultDomainDirectory,CurLang).gettext(StripCR(utf8encode(szMsgId)))));\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    if (szMsgId<>'') and (Result='') then\r
+      DebugWriteln (Format('Error: Translation of %s was an empty string. This may never occur.',[szMsgId]));\r
+    {$endif}\r
+  end;\r
+end;\r
+\r
+function TGnuGettextInstance.GetCurrentLanguage: string;\r
+begin\r
+  Result:=curlang;\r
+end;\r
+\r
+function TGnuGettextInstance.getcurrenttextdomain: string;\r
+begin\r
+  Result := curmsgdomain;\r
+end;\r
+\r
+{$ifndef DELPHI5OROLDER}\r
+function TGnuGettextInstance.gettext(\r
+  const szMsgId: ansistring): widestring;\r
+begin\r
+  Result := dgettext(curmsgdomain, szMsgId);\r
+end;\r
+{$endif}\r
+\r
+function TGnuGettextInstance.gettext(\r
+  const szMsgId: widestring): widestring;\r
+begin\r
+  Result := dgettext(curmsgdomain, szMsgId);\r
+end;\r
+\r
+procedure TGnuGettextInstance.textdomain(const szDomain: string);\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Changed text domain to "'+szDomain+'"');\r
+  {$endif}\r
+  curmsgdomain := szDomain;\r
+  WhenNewDomain (szDomain);\r
+end;\r
+\r
+function TGnuGettextInstance.TP_CreateRetranslator : TExecutable;\r
+var\r
+  ttpr:TTP_Retranslator;\r
+begin\r
+  ttpr:=TTP_Retranslator.Create;\r
+  ttpr.Instance:=self;\r
+  TP_Retranslator:=ttpr;\r
+  Result:=ttpr;\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('A retranslator was created.');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TP_GlobalHandleClass(HClass: TClass;\r
+  Handler: TTranslator);\r
+var\r
+  cm:TClassMode;\r
+  i:integer;\r
+begin\r
+  for i:=0 to TP_GlobalClassHandling.Count-1 do begin\r
+    cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode;\r
+    if cm.HClass=HClass then\r
+      raise EGGProgrammingError.Create ('You cannot set a handler for a class that has already been assigned otherwise.');\r
+    if HClass.InheritsFrom(cm.HClass) then begin\r
+      // This is the place to insert this class\r
+      cm:=TClassMode.Create;\r
+      cm.HClass:=HClass;\r
+      cm.SpecialHandler:=Handler;\r
+      TP_GlobalClassHandling.Insert(i,cm);\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('A handler was set for class '+HClass.ClassName+'.');\r
+      {$endif}\r
+      exit;\r
+    end;\r
+  end;\r
+  cm:=TClassMode.Create;\r
+  cm.HClass:=HClass;\r
+  cm.SpecialHandler:=Handler;\r
+  TP_GlobalClassHandling.Add(cm);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('A handler was set for class '+HClass.ClassName+'.');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TP_GlobalIgnoreClass(IgnClass: TClass);\r
+var\r
+  cm:TClassMode;\r
+  i:integer;\r
+begin\r
+  for i:=0 to TP_GlobalClassHandling.Count-1 do begin\r
+    cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode;\r
+    if cm.HClass=IgnClass then\r
+      raise EGGProgrammingError.Create ('You cannot add a class to the ignore list that is already on that list: '+IgnClass.ClassName+'. You should keep all TP_Global functions in one place in your source code.');\r
+    if IgnClass.InheritsFrom(cm.HClass) then begin\r
+      // This is the place to insert this class\r
+      cm:=TClassMode.Create;\r
+      cm.HClass:=IgnClass;\r
+      TP_GlobalClassHandling.Insert(i,cm);\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Globally, class '+IgnClass.ClassName+' is being ignored.');\r
+      {$endif}\r
+      exit;\r
+    end;\r
+  end;\r
+  cm:=TClassMode.Create;\r
+  cm.HClass:=IgnClass;\r
+  TP_GlobalClassHandling.Add(cm);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Globally, class '+IgnClass.ClassName+' is being ignored.');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TP_GlobalIgnoreClassProperty(\r
+  IgnClass: TClass; propertyname: string);\r
+var\r
+  cm:TClassMode;\r
+  i,idx:integer;\r
+begin\r
+  propertyname:=uppercase(propertyname);\r
+  for i:=0 to TP_GlobalClassHandling.Count-1 do begin\r
+    cm:=TObject(TP_GlobalClassHandling.Items[i]) as TClassMode;\r
+    if cm.HClass=IgnClass then begin\r
+      if Assigned(cm.SpecialHandler) then\r
+        raise EGGProgrammingError.Create ('You cannot ignore a class property for a class that has a handler set.');\r
+      if not cm.PropertiesToIgnore.Find(propertyname,idx) then\r
+        cm.PropertiesToIgnore.Add(propertyname);\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.');\r
+      {$endif}\r
+      exit;\r
+    end;\r
+    if IgnClass.InheritsFrom(cm.HClass) then begin\r
+      // This is the place to insert this class\r
+      cm:=TClassMode.Create;\r
+      cm.HClass:=IgnClass;\r
+      cm.PropertiesToIgnore.Add(propertyname);\r
+      TP_GlobalClassHandling.Insert(i,cm);\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.');\r
+      {$endif}\r
+      exit;\r
+    end;\r
+  end;\r
+  cm:=TClassMode.Create;\r
+  cm.HClass:=IgnClass;\r
+  cm.PropertiesToIgnore.Add(propertyname);\r
+  TP_GlobalClassHandling.Add(cm);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TP_Ignore(AnObject: TObject;\r
+  const name: string);\r
+begin\r
+  TP_IgnoreList.Add(uppercase(name));\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('On object with class name '+AnObject.ClassName+', ignore is set on '+name);\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TranslateComponent(AnObject: TComponent;\r
+  const TextDomain: string);\r
+var\r
+  comp:TGnuGettextComponentMarker;\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('======================================================================');\r
+  DebugWriteln ('TranslateComponent() was called for a component with name '+AnObject.Name+'.');\r
+  {$endif}\r
+  comp:=AnObject.FindComponent('GNUgettextMarker') as TGnuGettextComponentMarker;\r
+  if comp=nil then begin\r
+    comp:=TGnuGettextComponentMarker.Create (nil);\r
+    comp.Name:='GNUgettextMarker';\r
+    comp.Retranslator:=TP_CreateRetranslator;\r
+    TranslateProperties (AnObject, TextDomain);\r
+    AnObject.InsertComponent(comp);\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('This is the first time, that this component has been translated. A retranslator component has been created for this component.');\r
+    {$endif}\r
+  end else begin\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('This is not the first time, that this component has been translated.');\r
+    {$endif}\r
+    if comp.LastLanguage<>curlang then begin\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('ERROR: TranslateComponent() was called twice with different languages. This indicates an attempt to switch language at runtime, but by using TranslateComponent every time. This API has changed - please use RetranslateComponent() instead.');\r
+      {$endif}\r
+      {$ifdef mswindows}\r
+      MessageBox (0,'This application tried to switch the language, but in an incorrect way. The programmer needs to replace a call to TranslateComponent with a call to RetranslateComponent(). The programmer should see the changelog of gnugettext.pas for more information.','Error',MB_OK);\r
+      {$else}\r
+      writeln (stderr,'This application tried to switch the language, but in an incorrect way. The programmer needs to replace a call to TranslateComponent with a call to RetranslateComponent(). The programmer should see the changelog of gnugettext.pas for more information.');\r
+      {$endif}\r
+    end else begin\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('ERROR: TranslateComponent has been called twice, but with the same language chosen. This is a mistake, but in order to prevent that the application breaks, no exception is raised.');\r
+      {$endif}\r
+    end;\r
+  end;\r
+  comp.LastLanguage:=curlang;\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('======================================================================');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TranslateProperty (AnObject:TObject; PropInfo:PPropInfo; TodoList:TStrings; const TextDomain:string);\r
+var\r
+  {$ifdef DELPHI5OROLDER}\r
+  ws: string;\r
+  old: string;\r
+  {$endif}\r
+  {$ifndef DELPHI5OROLDER}\r
+  ppi:PPropInfo;\r
+  ws: WideString;\r
+  old: WideString;\r
+  {$endif}\r
+  obj:TObject;\r
+  Propname:string;\r
+begin\r
+  PropName:=PropInfo^.Name;\r
+  try\r
+    // Translate certain types of properties\r
+    case PropInfo^.PropType^.Kind of\r
+      tkString, tkLString, tkWString:\r
+        begin\r
+          {$ifdef DXGETTEXTDEBUG}\r
+          DebugWriteln ('Translating '+AnObject.ClassName+'.'+PropName);\r
+          {$endif}\r
+          {$ifdef DELPHI5OROLDER}\r
+          old := GetStrProp(AnObject, PropName);\r
+          {$endif}\r
+          {$ifndef DELPHI5OROLDER}\r
+          if PropInfo^.PropType^.Kind<>tkWString then\r
+            old := ansi2wide(GetStrProp(AnObject, PropName))\r
+          else\r
+            old := GetWideStrProp(AnObject, PropName);\r
+          {$endif}\r
+          {$ifdef DXGETTEXTDEBUG}\r
+          if old='' then\r
+            DebugWriteln ('(Empty, not translated)')\r
+          else\r
+            DebugWriteln ('Old value: "'+old+'"');\r
+          {$endif}\r
+          if (old <> '') and (IsWriteProp(PropInfo)) then begin\r
+            if TP_Retranslator<>nil then\r
+              (TP_Retranslator as TTP_Retranslator).Remember(AnObject, PropName, old);\r
+            ws := dgettext(textdomain,old);\r
+            if ws <> old then begin\r
+              {$ifdef DELPHI5OROLDER}\r
+              SetStrProp(AnObject, PropName, ws);\r
+              {$endif}\r
+              {$ifndef DELPHI5OROLDER}\r
+              ppi:=GetPropInfo(AnObject, Propname);\r
+              if ppi<>nil then begin\r
+                SetWideStrProp(AnObject, ppi, ws);\r
+              end else begin\r
+                {$ifdef DXGETTEXTDEBUG}\r
+                DebugWriteln ('ERROR: Property disappeared: '+Propname+' for object of type '+AnObject.ClassName);\r
+                {$endif}\r
+              end;\r
+              {$endif}\r
+            end;\r
+          end;\r
+        end { case item };\r
+      tkClass:\r
+        begin\r
+//          obj:=GetObjectProp(AnObject, PropName);\r
+//          if obj<>nil then\r
+//            TodoList.AddObject ('',obj);\r
+        end { case item };\r
+      end { case };\r
+  except\r
+    on E:Exception do\r
+      raise EGGComponentError.Create ('Property cannot be translated.'+sLineBreak+\r
+        'Add TP_GlobalIgnoreClassProperty('+AnObject.ClassName+','''+PropName+''') to your source code or use'+sLineBreak+\r
+        'TP_Ignore (self,''.'+PropName+''') to prevent this message.'+sLineBreak+\r
+        'Reason: '+e.Message);\r
+  end;\r
+end;\r
+\r
+procedure TGnuGettextInstance.TranslateProperties(AnObject: TObject; textdomain:string='');\r
+var\r
+  TodoList:TStringList; // List of Name/TObject's that is to be processed\r
+  DoneList:TStringList; // List of hex codes representing pointers to objects that have been done\r
+  i, j, Count: integer;\r
+  PropList: PPropList;\r
+  UPropName: string;\r
+  PropInfo: PPropInfo;\r
+  comp:TComponent;\r
+  cm,currentcm:TClassMode;\r
+  ObjectPropertyIgnoreList:TStringList;\r
+  objid, Name:string;\r
+  {$ifdef DELPHI5OROLDER}\r
+  Data:PTypeData;\r
+  {$endif}\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('----------------------------------------------------------------------');\r
+  DebugWriteln ('TranslateProperties() was called for an object of class '+AnObject.ClassName+' with domain "'+textdomain+'".');\r
+  {$endif}\r
+  if textdomain='' then\r
+    textdomain:=curmsgdomain;\r
+  if TP_Retranslator<>nil then\r
+    (TP_Retranslator as TTP_Retranslator).TextDomain:=textdomain;\r
+  DoneList:=TStringList.Create;\r
+  TodoList:=TStringList.Create;\r
+  ObjectPropertyIgnoreList:=TStringList.Create;\r
+  try\r
+    TodoList.AddObject('', AnObject);\r
+    DoneList.Sorted:=True;\r
+    ObjectPropertyIgnoreList.Sorted:=True;\r
+    {$ifndef DELPHI5OROLDER}\r
+    ObjectPropertyIgnoreList.Duplicates:=dupIgnore;\r
+    ObjectPropertyIgnoreList.CaseSensitive:=False;\r
+    DoneList.Duplicates:=dupError;\r
+    DoneList.CaseSensitive:=True;\r
+    {$endif}\r
+\r
+    while TodoList.Count<>0 do begin\r
+      AnObject:=TodoList.Objects[0];\r
+      Name:=TodoList.Strings[0];\r
+      TodoList.Delete(0);\r
+      if (AnObject<>nil) and (AnObject is TPersistent) then begin\r
+        // Make sure each object is only translated once\r
+        Assert (sizeof(integer)=sizeof(TObject));\r
+        objid:=IntToHex(integer(AnObject),8);\r
+        if DoneList.Find(objid,i) then begin\r
+          continue;\r
+        end else begin\r
+          DoneList.Add(objid);\r
+        end;\r
+\r
+        ObjectPropertyIgnoreList.Clear;\r
+\r
+        // Find out if there is special handling of this object\r
+        currentcm:=nil;\r
+        // First check the local handling instructions\r
+        for j:=0 to TP_ClassHandling.Count-1 do begin\r
+          cm:=TObject(TP_ClassHandling.Items[j]) as TClassMode;\r
+          if AnObject.InheritsFrom(cm.HClass) then begin\r
+            if cm.PropertiesToIgnore.Count<>0 then begin\r
+              ObjectPropertyIgnoreList.AddStrings(cm.PropertiesToIgnore);\r
+            end else begin\r
+              // Ignore the entire class\r
+              currentcm:=cm;\r
+              break;\r
+            end;\r
+          end;\r
+        end;\r
+        // Then check the global handling instructions\r
+        if currentcm=nil then\r
+        for j:=0 to TP_GlobalClassHandling.Count-1 do begin\r
+          cm:=TObject(TP_GlobalClassHandling.Items[j]) as TClassMode;\r
+          if AnObject.InheritsFrom(cm.HClass) then begin\r
+            if cm.PropertiesToIgnore.Count<>0 then begin\r
+              ObjectPropertyIgnoreList.AddStrings(cm.PropertiesToIgnore);\r
+            end else begin\r
+              // Ignore the entire class\r
+              currentcm:=cm;\r
+              break;\r
+            end;\r
+          end;\r
+        end;\r
+        if currentcm<>nil then begin\r
+          ObjectPropertyIgnoreList.Clear;\r
+          // Ignore or use special handler\r
+          if Assigned(currentcm.SpecialHandler) then begin\r
+            currentcm.SpecialHandler (AnObject);\r
+            {$ifdef DXGETTEXTDEBUG}\r
+            DebugWriteln ('Special handler activated for '+AnObject.ClassName);\r
+            {$endif}\r
+          end else begin\r
+            {$ifdef DXGETTEXTDEBUG}\r
+            DebugWriteln ('Ignoring object '+AnObject.ClassName);\r
+            {$endif}\r
+          end;\r
+          continue;\r
+        end;\r
+\r
+        {$ifdef DELPHI5OROLDER}\r
+        if AnObject.ClassInfo=nil then begin\r
+          {$ifdef DXGETTEXTDEBUG}\r
+          DebugWriteln ('ClassInfo=nil encountered for class '+AnObject.ClassName+'. Translation of that component has stopped. You should ignore this object.');\r
+          {$endif}\r
+          continue;\r
+        end;\r
+        Data := GetTypeData(AnObject.Classinfo);\r
+        Count := Data^.PropCount;\r
+        GetMem(PropList, Count * Sizeof(PPropInfo));\r
+        {$endif}\r
+        {$ifndef DELPHI5OROLDER}\r
+        Count := GetPropList(AnObject, PropList);\r
+        {$endif}\r
+        try\r
+          {$ifdef DELPHI5OROLDER}\r
+          GetPropInfos(AnObject.ClassInfo, PropList);\r
+          {$endif}\r
+          for j := 0 to Count - 1 do begin\r
+            PropInfo := PropList[j];\r
+            UPropName:=uppercase(PropInfo^.Name);\r
+            // Ignore properties that are meant to be ignored\r
+            if ((currentcm=nil) or (not currentcm.PropertiesToIgnore.Find(UPropName,i))) and\r
+               (not TP_IgnoreList.Find(Name+'.'+UPropName,i)) and\r
+               (not ObjectPropertyIgnoreList.Find(UPropName,i)) then begin\r
+              TranslateProperty (AnObject,PropInfo,TodoList,TextDomain);\r
+            end;  // if\r
+          end;  // for\r
+        finally\r
+          {$ifdef DELPHI5OROLDER}\r
+          FreeMem(PropList, Data^.PropCount * Sizeof(PPropInfo));\r
+          {$endif}\r
+          {$ifndef DELPHI5OROLDER}\r
+          if Count<>0 then\r
+            FreeMem (PropList);\r
+          {$endif}\r
+        end;\r
+        if AnObject is TStrings then begin\r
+          if ((AnObject as TStrings).Text<>'') and (TP_Retranslator<>nil) then\r
+            (TP_Retranslator as TTP_Retranslator).Remember(AnObject, 'Text', (AnObject as TStrings).Text);\r
+          TranslateStrings (AnObject as TStrings,TextDomain);\r
+        end;\r
+        // Check for TCollection\r
+        if AnObject is TCollection then begin\r
+          for i := 0 to (AnObject as TCollection).Count - 1 do\r
+            TodoList.AddObject('',(AnObject as TCollection).Items[i]);\r
+        end;\r
+        if AnObject is TComponent then begin\r
+          for i := 0 to TComponent(AnObject).ComponentCount - 1 do begin\r
+            comp:=TComponent(AnObject).Components[i];\r
+            if (not TP_IgnoreList.Find(uppercase(comp.Name),j)) then begin\r
+              TodoList.AddObject(uppercase(comp.Name),comp);\r
+            end;\r
+          end;\r
+        end;\r
+      end { if AnObject<>nil };\r
+    end { while todolist.count<>0 };\r
+  finally\r
+    FreeAndNil (todolist);\r
+    FreeAndNil (ObjectPropertyIgnoreList);\r
+    FreeAndNil (DoneList);\r
+  end;\r
+  FreeTP_ClassHandlingItems;\r
+  TP_IgnoreList.Clear;\r
+  TP_Retranslator:=nil;\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('----------------------------------------------------------------------');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.UseLanguage(LanguageCode: string);\r
+var\r
+  i,p:integer;\r
+  dom:TDomain;\r
+  l2:string[2];\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln('UseLanguage('''+LanguageCode+'''); called');\r
+  {$endif}\r
+\r
+  if LanguageCode='' then begin\r
+    LanguageCode:=GGGetEnvironmentVariable('LANG');\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('LANG env variable is '''+LanguageCode+'''.');\r
+    {$endif}\r
+    {$ifdef MSWINDOWS}\r
+    if LanguageCode='' then begin\r
+      LanguageCode:=GetWindowsLanguage;\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Found Windows language code to be '''+LanguageCode+'''.');\r
+      {$endif}\r
+    end;\r
+    {$endif}\r
+    p:=pos('.',LanguageCode);\r
+    if p<>0 then\r
+      LanguageCode:=copy(LanguageCode,1,p-1);\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('Language code that will be set is '''+LanguageCode+'''.');\r
+    {$endif}\r
+  end;\r
+\r
+  curlang := LanguageCode;\r
+  for i:=0 to domainlist.Count-1 do begin\r
+    dom:=domainlist.Objects[i] as TDomain;\r
+    dom.SetLanguageCode (curlang);\r
+  end;\r
+\r
+  l2:=lowercase(copy(curlang,1,2));\r
+  if (l2='en') or (l2='de') then curGetPluralForm:=GetPluralForm2EN else\r
+  if (l2='hu') or (l2='ko') or (l2='zh') or (l2='ja') or (l2='tr') then curGetPluralForm:=GetPluralForm1 else\r
+  if (l2='fr') or (l2='fa') or (lowercase(curlang)='pt_br') then curGetPluralForm:=GetPluralForm2FR else\r
+  if (l2='lv') then curGetPluralForm:=GetPluralForm3LV else\r
+  if (l2='ga') then curGetPluralForm:=GetPluralForm3GA else\r
+  if (l2='lt') then curGetPluralForm:=GetPluralForm3LT else\r
+  if (l2='ru') or (l2='cs') or (l2='sk') or (l2='uk') or (l2='hr') then curGetPluralForm:=GetPluralForm3RU else\r
+  if (l2='pl') then curGetPluralForm:=GetPluralForm3PL else\r
+  if (l2='sl') then curGetPluralForm:=GetPluralForm4SL else begin\r
+    curGetPluralForm:=GetPluralForm2EN;\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('Plural form for the language was not found. English plurality system assumed.');\r
+    {$endif}\r
+  end;\r
+\r
+  WhenNewLanguage (curlang);\r
+\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln('');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TranslateStrings(sl: TStrings;const TextDomain:string);\r
+var\r
+  line: string;\r
+  i: integer;\r
+  s:TStringList;\r
+begin\r
+  if sl.Count > 0 then begin\r
+    sl.BeginUpdate;\r
+    try\r
+      s:=TStringList.Create;\r
+      try\r
+        s.Assign (sl);\r
+        for i:=0 to s.Count-1 do begin\r
+          line:=s.Strings[i];\r
+          if line<>'' then\r
+            s.Strings[i]:=dgettext(TextDomain,line);\r
+        end;\r
+        sl.Assign(s);\r
+      finally\r
+        FreeAndNil (s);\r
+      end;\r
+    finally\r
+      sl.EndUpdate;\r
+    end;\r
+  end;\r
+end;\r
+\r
+function TGnuGettextInstance.GetTranslatorNameAndEmail: widestring;\r
+begin\r
+  Result:=GetTranslationProperty('LAST-TRANSLATOR');\r
+end;\r
+\r
+function TGnuGettextInstance.GetTranslationProperty(\r
+  const Propertyname: string): WideString;\r
+begin\r
+  Result:=getdomain(curmsgdomain,DefaultDomainDirectory,CurLang).GetTranslationProperty (Propertyname);\r
+end;\r
+\r
+function TGnuGettextInstance.dngettext(const szDomain: string; const singular, plural: widestring;\r
+  Number: Integer): widestring;\r
+var\r
+  org,trans:widestring;\r
+  idx:integer;\r
+  p:integer;\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('dngettext translation (domain '+szDomain+', number is '+IntTostr(Number)+') of '+singular+'/'+plural);\r
+  {$endif}\r
+  org:=singular+#0+plural;\r
+  trans:=dgettext(szDomain,org);\r
+  if org=trans then begin\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('Translation was equal to english version. English plural forms assumed.');\r
+    {$endif}\r
+    idx:=GetPluralForm2EN(Number)\r
+  end else\r
+    idx:=curGetPluralForm(Number);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Index '+IntToStr(idx)+' will be used');\r
+  {$endif}\r
+  while true do begin\r
+    p:=pos(#0,trans);\r
+    if p=0 then begin\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Last translation used: '+utf8encode(trans));\r
+      {$endif}\r
+      Result:=trans;\r
+      exit;\r
+    end;\r
+    if idx=0 then begin\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Translation found: '+utf8encode(trans));\r
+      {$endif}\r
+      Result:=copy(trans,1,p-1);\r
+      exit;\r
+    end;\r
+    delete (trans,1,p);\r
+    dec (idx);\r
+  end;\r
+end;\r
+\r
+{$ifndef DELPHI5OROLDER}\r
+function TGnuGettextInstance.ngettext(const singular, plural: ansistring;\r
+  Number: Integer): widestring;\r
+begin\r
+  Result := dngettext(curmsgdomain, singular, plural, Number);\r
+end;\r
+{$endif}\r
+\r
+function TGnuGettextInstance.ngettext(const singular, plural: widestring;\r
+  Number: Integer): widestring;\r
+begin\r
+  Result := dngettext(curmsgdomain, singular, plural, Number);\r
+end;\r
+\r
+procedure TGnuGettextInstance.WhenNewDomain(const TextDomain: string);\r
+begin\r
+  // This is meant to be empty.\r
+end;\r
+\r
+procedure TGnuGettextInstance.WhenNewLanguage(const LanguageID: string);\r
+begin\r
+  // This is meant to be empty.\r
+end;\r
+\r
+procedure TGnuGettextInstance.WhenNewDomainDirectory(const TextDomain,\r
+  Directory: string);\r
+begin\r
+  // This is meant to be empty.\r
+end;\r
+\r
+procedure TGnuGettextInstance.GetListOfLanguages(const domain: string;\r
+  list: TStrings);\r
+begin\r
+  getdomain(Domain,DefaultDomainDirectory,CurLang).GetListOfLanguages(list);\r
+end;\r
+\r
+procedure TGnuGettextInstance.bindtextdomainToFile(const szDomain,\r
+  filename: string);\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Text domain "'+szDomain+'" is now bound to file named "'+filename+'"');\r
+  {$endif}\r
+  getdomain(szDomain,DefaultDomainDirectory,CurLang).SetFilename (filename);\r
+end;\r
+\r
+procedure TGnuGettextInstance.DebugLogPause(PauseEnabled: boolean);\r
+begin\r
+  DebugLogOutputPaused:=PauseEnabled;\r
+end;\r
+\r
+procedure TGnuGettextInstance.DebugLogToFile(const filename: string; append:boolean=false);\r
+{$ifdef DXGETTEXTDEBUG}\r
+var\r
+  fs:TFileStream;\r
+  marker:string;\r
+{$endif}\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  // Create the file if needed\r
+  if (not fileexists(filename)) or (not append) then\r
+    fileclose (filecreate (filename));\r
+\r
+  // Open file\r
+  fs:=TFileStream.Create (filename,fmOpenWrite or fmShareDenyWrite);\r
+  if append then\r
+    fs.Seek(0,soFromEnd);\r
+\r
+  // Write header if appending\r
+  if fs.Position<>0 then begin\r
+    marker:=sLineBreak+'==========================================================================='+sLineBreak;\r
+    fs.WriteBuffer(marker[1],length(marker));\r
+  end;\r
+\r
+  // Copy the memorystream contents to the file\r
+  DebugLog.Seek(0,soFromBeginning);\r
+  fs.CopyFrom(DebugLog,0);\r
+\r
+  // Make DebugLog point to the filestream\r
+  FreeAndNil (DebugLog);\r
+  DebugLog:=fs;\r
+{$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.DebugWriteln(line: ansistring);\r
+Var\r
+  Discard: Boolean;\r
+begin\r
+  Assert (DebugLogCS<>nil);\r
+  Assert (DebugLog<>nil);\r
+\r
+  DebugLogCS.BeginWrite;\r
+  try\r
+    if DebugLogOutputPaused then\r
+      exit;\r
+\r
+    if Assigned (fOnDebugLine) then begin\r
+      Discard := True;\r
+      fOnDebugLine (Self, Line, Discard);\r
+      If Discard then Exit;\r
+    end;\r
+\r
+    line:=line+sLineBreak;\r
+\r
+    // Ensure that memory usage doesn't get too big.\r
+    if (DebugLog is TMemoryStream) and (DebugLog.Position>1000000) then begin\r
+      line:=sLineBreak+sLineBreak+sLineBreak+sLineBreak+sLineBreak+\r
+            'Debug log halted because memory usage grew too much.'+sLineBreak+\r
+            'Specify a filename to store the debug log in or disable debug loggin in gnugettext.pas.'+\r
+            sLineBreak+sLineBreak+sLineBreak+sLineBreak+sLineBreak;\r
+      DebugLogOutputPaused:=True;\r
+    end;\r
+    DebugLog.WriteBuffer(line[1],length(line));\r
+  finally\r
+    DebugLogCS.EndWrite;\r
+  end;\r
+end;\r
+\r
+function TGnuGettextInstance.Getdomain(const domain, DefaultDomainDirectory, CurLang: string): TDomain;\r
+// Retrieves the TDomain object for the specified domain.\r
+// Creates one, if none there, yet.\r
+var\r
+  idx: integer;\r
+begin\r
+  idx := domainlist.IndexOf(Domain);\r
+  if idx = -1 then begin\r
+    Result := TDomain.Create;\r
+    Result.DebugLogger:=DebugWriteln;\r
+    Result.Domain := Domain;\r
+    Result.Directory := DefaultDomainDirectory;\r
+    Result.SetLanguageCode(curlang);\r
+    domainlist.AddObject(Domain, Result);\r
+  end else begin\r
+    Result := domainlist.Objects[idx] as TDomain;\r
+  end;\r
+end;\r
+\r
+function TGnuGettextInstance.LoadResString(\r
+  ResStringRec: PResStringRec): widestring;\r
+{$ifdef MSWINDOWS}\r
+var\r
+  Len: Integer;\r
+  Buffer: array [0..1023] of char;\r
+{$endif}\r
+{$ifdef LINUX }\r
+const\r
+  ResStringTableLen = 16;\r
+type\r
+  ResStringTable = array [0..ResStringTableLen-1] of LongWord;\r
+var\r
+  Handle: TResourceHandle;\r
+  Tab: ^ResStringTable;\r
+  ResMod: HMODULE;\r
+{$endif }\r
+begin\r
+  if ResStringRec=nil then\r
+    exit;\r
+  if ResStringRec.Identifier>=64*1024 then begin\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('LoadResString was given an invalid ResStringRec.Identifier');\r
+    {$endif}\r
+    Result:='ERROR';\r
+    exit;\r
+  end else begin\r
+    {$ifdef LINUX}\r
+    // This works with Unicode if the Linux has utf-8 character set\r
+    // Result:=System.LoadResString(ResStringRec);\r
+    ResMod:=FindResourceHInstance(ResStringRec^.Module^);\r
+    Handle:=FindResource(ResMod,\r
+      PChar(ResStringRec^.Identifier div ResStringTableLen), PChar(6));   // RT_STRING\r
+    Tab:=Pointer(LoadResource(ResMod, Handle));\r
+    if Tab=nil then\r
+      Result:=''\r
+    else\r
+      Result:=PWideChar(PChar(Tab)+Tab[ResStringRec^.Identifier mod ResStringTableLen]);\r
+    {$endif}\r
+    {$ifdef MSWINDOWS}\r
+    if not Win32PlatformIsUnicode then begin\r
+      SetString(Result, Buffer,\r
+        LoadString(FindResourceHInstance(ResStringRec.Module^),\r
+          ResStringRec.Identifier, Buffer, SizeOf(Buffer)))\r
+    end else begin\r
+      Result := '';\r
+      Len := 0;\r
+      While Len = Length(Result) do begin\r
+        if Length(Result) = 0 then\r
+          SetLength(Result, 1024)\r
+        else\r
+          SetLength(Result, Length(Result) * 2);\r
+        Len := LoadStringW(FindResourceHInstance(ResStringRec.Module^),\r
+          ResStringRec.Identifier, PWideChar(Result), Length(Result));\r
+      end;\r
+      SetLength(Result, Len);\r
+    end;\r
+    {$endif}\r
+  end;\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Loaded resourcestring: '+utf8encode(Result));\r
+  {$endif}\r
+  if CreatorThread<>GetCurrentThreadId then begin\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('LoadResString was called from an invalid thread. Resourcestring was not translated.');\r
+    {$endif}\r
+  end else\r
+    Result:=ResourceStringGettext(Result);\r
+end;\r
+\r
+procedure TGnuGettextInstance.RetranslateComponent(AnObject: TComponent;\r
+  const TextDomain: string);\r
+var\r
+  comp:TGnuGettextComponentMarker;\r
+begin\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('======================================================================');\r
+  DebugWriteln ('RetranslateComponent() was called for a component with name '+AnObject.Name+'.');\r
+  {$endif}\r
+  comp:=AnObject.FindComponent('GNUgettextMarker') as TGnuGettextComponentMarker;\r
+  if comp=nil then begin\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    DebugWriteln ('Retranslate was called on an object that has not been translated before. An Exception is being raised.');\r
+    {$endif}\r
+    raise EGGProgrammingError.Create ('Retranslate was called on an object that has not been translated before. Please use TranslateComponent() before RetranslateComponent().');\r
+  end else begin\r
+    if comp.LastLanguage<>curlang then begin\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('The retranslator is being executed.');\r
+      {$endif}\r
+      comp.Retranslator.Execute;\r
+    end else begin\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('The language has not changed. The retranslator is not executed.');\r
+      {$endif}\r
+    end;\r
+  end;\r
+  comp.LastLanguage:=curlang;\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('======================================================================');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TP_IgnoreClass(IgnClass: TClass);\r
+var\r
+  cm:TClassMode;\r
+  i:integer;\r
+begin\r
+  for i:=0 to TP_ClassHandling.Count-1 do begin\r
+    cm:=TObject(TP_ClassHandling.Items[i]) as TClassMode;\r
+    if cm.HClass=IgnClass then\r
+      raise EGGProgrammingError.Create ('You cannot add a class to the ignore list that is already on that list: '+IgnClass.ClassName+'.');\r
+    if IgnClass.InheritsFrom(cm.HClass) then begin\r
+      // This is the place to insert this class\r
+      cm:=TClassMode.Create;\r
+      cm.HClass:=IgnClass;\r
+      TP_ClassHandling.Insert(i,cm);\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Locally, class '+IgnClass.ClassName+' is being ignored.');\r
+      {$endif}\r
+      exit;\r
+    end;\r
+  end;\r
+  cm:=TClassMode.Create;\r
+  cm.HClass:=IgnClass;\r
+  TP_ClassHandling.Add(cm);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Locally, class '+IgnClass.ClassName+' is being ignored.');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.TP_IgnoreClassProperty(IgnClass: TClass;\r
+  propertyname: string);\r
+var\r
+  cm:TClassMode;\r
+  i:integer;\r
+begin\r
+  propertyname:=uppercase(propertyname);\r
+  for i:=0 to TP_ClassHandling.Count-1 do begin\r
+    cm:=TObject(TP_ClassHandling.Items[i]) as TClassMode;\r
+    if cm.HClass=IgnClass then begin\r
+      if Assigned(cm.SpecialHandler) then\r
+        raise EGGProgrammingError.Create ('You cannot ignore a class property for a class that has a handler set.');\r
+      cm.PropertiesToIgnore.Add(propertyname);\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Globally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.');\r
+      {$endif}\r
+      exit;\r
+    end;\r
+    if IgnClass.InheritsFrom(cm.HClass) then begin\r
+      // This is the place to insert this class\r
+      cm:=TClassMode.Create;\r
+      cm.HClass:=IgnClass;\r
+      cm.PropertiesToIgnore.Add(propertyname);\r
+      TP_ClassHandling.Insert(i,cm);\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugWriteln ('Locally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.');\r
+      {$endif}\r
+      exit;\r
+    end;\r
+  end;\r
+  cm:=TClassMode.Create;\r
+  cm.HClass:=IgnClass;\r
+  cm.PropertiesToIgnore.Add(propertyname);\r
+  TP_GlobalClassHandling.Add(cm);\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugWriteln ('Locally, the '+propertyname+' property of class '+IgnClass.ClassName+' is being ignored.');\r
+  {$endif}\r
+end;\r
+\r
+procedure TGnuGettextInstance.FreeTP_ClassHandlingItems;\r
+begin\r
+  while TP_ClassHandling.Count<>0 do begin\r
+    TObject(TP_ClassHandling.Items[0]).Free;\r
+    TP_ClassHandling.Delete(0);\r
+  end;\r
+end;\r
+\r
+function TGnuGettextInstance.ansi2wide(const s: ansistring): widestring;\r
+{$ifdef MSWindows}\r
+var\r
+  len:integer;\r
+{$endif}\r
+begin\r
+{$ifdef MSWindows}\r
+  if DesignTimeCodePage=CP_ACP then begin\r
+    // No design-time codepage specified. Using runtime codepage instead.\r
+{$endif}\r
+    Result:=s;\r
+{$ifdef MSWindows}\r
+  end else begin\r
+    len:=length(s);\r
+    if len=0 then\r
+      Result:=''\r
+    else begin\r
+      SetLength (Result,len);\r
+      len:=MultiByteToWideChar(DesignTimeCodePage,0,pchar(s),len,pwidechar(Result),len);\r
+      if len=0 then\r
+        raise EGGAnsi2WideConvError.Create ('Cannot convert string to widestring:'+sLineBreak+s);\r
+      SetLength (Result,len);\r
+    end;\r
+  end;\r
+{$endif}\r
+end;\r
+\r
+{$ifndef DELPHI5OROLDER}\r
+function TGnuGettextInstance.dngettext(const szDomain: string; const singular,\r
+  plural: ansistring; Number: Integer): widestring;\r
+begin\r
+  Result:=dngettext (szDomain, ansi2wide(singular), ansi2wide(plural), Number);\r
+end;\r
+{$endif}\r
+\r
+{ TClassMode }\r
+\r
+constructor TClassMode.Create;\r
+begin\r
+  PropertiesToIgnore:=TStringList.Create;\r
+  PropertiesToIgnore.Sorted:=True;\r
+  PropertiesToIgnore.Duplicates:=dupError;\r
+  {$ifndef DELPHI5OROLDER}\r
+  PropertiesToIgnore.CaseSensitive:=False;\r
+  {$endif}\r
+end;\r
+\r
+destructor TClassMode.Destroy;\r
+begin\r
+  FreeAndNil (PropertiesToIgnore);\r
+  inherited;\r
+end;\r
+\r
+{ TFileLocator }\r
+\r
+procedure TFileLocator.Analyze;\r
+var\r
+  s:ansistring;\r
+  i:integer;\r
+  offset:int64;\r
+  fs:TFileStream;\r
+  fi:TEmbeddedFileInfo;\r
+  filename:string;\r
+begin\r
+  s:='6637DB2E-62E1-4A60-AC19-C23867046A89'#0#0#0#0#0#0#0#0;\r
+  s:=copy(s,length(s)-7,8);\r
+  offset:=0;\r
+  for i:=8 downto 1 do\r
+    offset:=offset shl 8+ord(s[i]);  \r
+  if offset=0 then\r
+    exit;\r
+  BaseDirectory:=ExtractFilePath(ExecutableFilename);\r
+  try\r
+    fs:=TFileStream.Create(ExecutableFilename,fmOpenRead or fmShareDenyNone);\r
+    try\r
+      while true do begin\r
+        fs.Seek(offset,soFromBeginning);\r
+        offset:=ReadInt64(fs);\r
+        if offset=0 then\r
+          exit;\r
+        fi:=TEmbeddedFileInfo.Create;\r
+        try\r
+          fi.Offset:=ReadInt64(fs);\r
+          fi.Size:=ReadInt64(fs);\r
+          SetLength (filename, offset-fs.position);\r
+          fs.ReadBuffer (filename[1],offset-fs.position);\r
+          filename:=trim(filename);\r
+          filelist.AddObject(filename,fi);\r
+        except\r
+          FreeAndNil (fi);\r
+          raise;\r
+        end;\r
+      end;\r
+    finally\r
+      FreeAndNil (fs);\r
+    end;\r
+  except\r
+    {$ifdef DXGETTEXTDEBUG}\r
+    raise;\r
+    {$endif}\r
+  end;\r
+end;\r
+\r
+constructor TFileLocator.Create;\r
+begin\r
+  MoFilesCS:=TMultiReadExclusiveWriteSynchronizer.Create;\r
+  MoFiles:=TStringList.Create;\r
+  filelist:=TStringList.Create;\r
+  {$ifdef LINUX}\r
+  filelist.Duplicates:=dupError;\r
+  filelist.CaseSensitive:=True;\r
+  {$endif}\r
+  MoFiles.Sorted:=True;\r
+  {$ifndef DELPHI5OROLDER}\r
+  MoFiles.Duplicates:=dupError;\r
+  MoFiles.CaseSensitive:=False;\r
+  {$ifdef MSWINDOWS}\r
+  filelist.Duplicates:=dupError;\r
+  filelist.CaseSensitive:=False;\r
+  {$endif}\r
+  {$endif}\r
+  filelist.Sorted:=True;\r
+end;\r
+\r
+destructor TFileLocator.Destroy;\r
+begin\r
+  while filelist.count<>0 do begin\r
+    filelist.Objects[0].Free;\r
+    filelist.Delete (0);\r
+  end;\r
+  FreeAndNil (filelist);\r
+  FreeAndNil (MoFiles);\r
+  FreeAndNil (MoFilesCS);\r
+  inherited;\r
+end;\r
+\r
+function TFileLocator.FileExists(filename: string): boolean;\r
+var\r
+  idx:integer;\r
+begin\r
+  if copy(filename,1,length(basedirectory))=basedirectory then \r
+    filename:=copy(filename,length(basedirectory)+1,maxint);\r
+  Result:=filelist.Find(filename,idx);\r
+end;\r
+\r
+function TFileLocator.GetMoFile(filename: string; DebugLogger:TDebugLogger): TMoFile;\r
+var\r
+  fi:TEmbeddedFileInfo;\r
+  idx:integer;\r
+  idxname:string;\r
+  Offset, Size: Int64;\r
+  realfilename:string;\r
+begin\r
+  // Find real filename\r
+  offset:=0;\r
+  size:=0;\r
+  realfilename:=filename;\r
+  if copy(filename,1,length(basedirectory))=basedirectory then begin\r
+    filename:=copy(filename,length(basedirectory)+1,maxint);\r
+    idx:=filelist.IndexOf(filename);\r
+    if idx<>-1 then begin\r
+      fi:=filelist.Objects[idx] as TEmbeddedFileInfo;\r
+      realfilename:=ExecutableFilename;\r
+      offset:=fi.offset;\r
+      size:=fi.size;\r
+      {$ifdef DXGETTEXTDEBUG}\r
+      DebugLogger ('Instead of '+filename+', using '+realfilename+' from offset '+IntTostr(offset)+', size '+IntToStr(size));\r
+      {$endif}\r
+    end;\r
+  end;\r
+\r
+\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  DebugLogger ('Reading .mo data from file '''+filename+'''');\r
+  {$endif}\r
+\r
+  // Find TMoFile object\r
+  MoFilesCS.BeginWrite;\r
+  try\r
+    idxname:=realfilename+#0+IntToStr(offset);\r
+    if MoFiles.Find(idxname, idx) then begin\r
+      Result:=MoFiles.Objects[idx] as TMoFile;\r
+    end else begin\r
+      Result:=TMoFile.Create (realfilename, Offset, Size);\r
+      MoFiles.AddObject(idxname, Result);\r
+    end;\r
+    Inc (Result.Users);\r
+  finally\r
+    MoFilesCS.EndWrite;\r
+  end;\r
+end;\r
+\r
+function TFileLocator.ReadInt64(str: TStream): int64;\r
+begin\r
+  Assert (sizeof(Result)=8);\r
+  str.ReadBuffer(Result,8);\r
+end;\r
+\r
+procedure TFileLocator.ReleaseMoFile(mofile: TMoFile);\r
+var\r
+  i:integer;\r
+begin\r
+  Assert (mofile<>nil);\r
+  \r
+  MoFilesCS.BeginWrite;\r
+  try\r
+    dec (mofile.Users);\r
+    if mofile.Users<=0 then begin\r
+      i:=MoFiles.Count-1;\r
+      while i>=0 do begin\r
+        if MoFiles.Objects[i]=mofile then begin\r
+          MoFiles.Delete(i);\r
+          FreeAndNil (mofile);\r
+          break;\r
+        end;\r
+        dec (i);\r
+      end;\r
+    end;\r
+  finally\r
+    MoFilesCS.EndWrite;\r
+  end;\r
+end;\r
+\r
+{ TTP_Retranslator }\r
+\r
+constructor TTP_Retranslator.Create;\r
+begin\r
+  list:=TList.Create;\r
+end;\r
+\r
+destructor TTP_Retranslator.Destroy;\r
+var\r
+  i:integer;\r
+begin\r
+  for i:=0 to list.Count-1 do\r
+    TObject(list.Items[i]).Free;\r
+  FreeAndNil (list);\r
+  inherited;\r
+end;\r
+\r
+procedure TTP_Retranslator.Execute;\r
+var\r
+  i:integer;\r
+  sl:TStrings;\r
+  item:TTP_RetranslatorItem;\r
+  newvalue:WideString;\r
+  {$ifndef DELPHI5OROLDER}\r
+  ppi:PPropInfo;\r
+  {$endif}\r
+begin\r
+  for i:=0 to list.Count-1 do begin\r
+    item:=TObject(list.items[i]) as TTP_RetranslatorItem;\r
+    if item.obj is TStrings then begin\r
+      // Since we don't know the order of items in sl, and don't have\r
+      // the original .Objects[] anywhere, we cannot anticipate anything\r
+      // about the current sl.Strings[] and sl.Objects[] values. We therefore\r
+      // have to discard both values. We can, however, set the original .Strings[]\r
+      // value into the list and retranslate that.\r
+      sl:=TStringList.Create;\r
+      try\r
+        sl.Text:=item.OldValue;\r
+        Instance.TranslateStrings(sl,textdomain);\r
+        (item.obj as TStrings).BeginUpdate;\r
+        try\r
+          (item.obj as TStrings).Text:=sl.Text;\r
+        finally\r
+          (item.obj as TStrings).EndUpdate;\r
+        end;\r
+      finally\r
+        FreeAndNil (sl);\r
+      end;\r
+    end else begin\r
+      newValue:=instance.dgettext(textdomain,item.OldValue);\r
+      {$ifdef DELPHI5OROLDER}\r
+      SetStrProp(item.obj, item.PropName, newValue);\r
+      {$endif}\r
+      {$ifndef DELPHI5OROLDER}\r
+      ppi:=GetPropInfo(item.obj, item.Propname);\r
+      if ppi<>nil then begin\r
+        SetWideStrProp(item.obj, ppi, newValue);\r
+      end else begin\r
+        {$ifdef DXGETTEXTDEBUG}\r
+        Instance.DebugWriteln ('ERROR: On retranslation, property disappeared: '+item.Propname+' for object of type '+item.obj.ClassName);\r
+        {$endif}\r
+      end;\r
+      {$endif}\r
+    end;\r
+  end;\r
+end;\r
+\r
+procedure TTP_Retranslator.Remember(obj: TObject; PropName: String;\r
+  OldValue: WideString);\r
+var\r
+  item:TTP_RetranslatorItem;\r
+begin\r
+  item:=TTP_RetranslatorItem.Create;\r
+  item.obj:=obj;\r
+  item.Propname:=Propname;\r
+  item.OldValue:=OldValue;\r
+  list.Add(item);\r
+end;\r
+\r
+{ TGnuGettextComponentMarker }\r
+\r
+destructor TGnuGettextComponentMarker.Destroy;\r
+begin\r
+  FreeAndNil (Retranslator);\r
+  inherited;\r
+end;\r
+\r
+{ THook }\r
+\r
+constructor THook.Create(OldProcedure, NewProcedure: pointer; FollowJump:boolean=false);\r
+{ Idea and original code from Igor Siticov }\r
+{ Modified by Jacques Garcia Vazquez and Lars Dybdahl }\r
+begin\r
+  {$ifndef CPU386}\r
+  'This procedure only works on Intel i386 compatible processors.'\r
+  {$endif}\r
+\r
+  oldproc:=OldProcedure;\r
+  newproc:=NewProcedure;\r
+\r
+  Reset (FollowJump);\r
+end;\r
+\r
+destructor THook.Destroy;\r
+begin\r
+  Shutdown;\r
+  inherited;\r
+end;\r
+\r
+procedure THook.Disable;\r
+begin\r
+  Assert (PatchPosition<>nil,'Patch position in THook was nil when Disable was called');\r
+  PatchPosition[0]:=Original[0];\r
+  PatchPosition[1]:=Original[1];\r
+  PatchPosition[2]:=Original[2];\r
+  PatchPosition[3]:=Original[3];\r
+  PatchPosition[4]:=Original[4];\r
+end;\r
+\r
+procedure THook.Enable;\r
+begin\r
+  Assert (PatchPosition<>nil,'Patch position in THook was nil when Enable was called');\r
+  PatchPosition[0]:=Patch[0];\r
+  PatchPosition[1]:=Patch[1];\r
+  PatchPosition[2]:=Patch[2];\r
+  PatchPosition[3]:=Patch[3];\r
+  PatchPosition[4]:=Patch[4];\r
+end;\r
+\r
+procedure THook.Reset(FollowJump: boolean);\r
+var\r
+  offset:integer;\r
+  {$ifdef LINUX}\r
+  p:pointer;\r
+  pagesize:integer;\r
+  {$endif}\r
+  {$ifdef MSWindows}\r
+  ov: cardinal;\r
+  {$endif}\r
+begin\r
+  if PatchPosition<>nil then\r
+    Shutdown;\r
+\r
+  patchPosition := OldProc;\r
+  if FollowJump and (Word(OldProc^) = $25FF) then begin\r
+    // This finds the correct procedure if a virtual jump has been inserted\r
+    // at the procedure address\r
+    Inc(Integer(patchPosition), 2); // skip the jump\r
+    patchPosition := pChar(Pointer(pointer(patchPosition)^)^);\r
+  end;\r
+  offset:=integer(NewProc)-integer(pointer(patchPosition))-5;\r
+\r
+  Patch[0] := char($E9);\r
+  Patch[1] := char(offset and 255);\r
+  Patch[2] := char((offset shr 8) and 255);\r
+  Patch[3] := char((offset shr 16) and 255);\r
+  Patch[4] := char((offset shr 24) and 255);\r
+\r
+  Original[0]:=PatchPosition[0];\r
+  Original[1]:=PatchPosition[1];\r
+  Original[2]:=PatchPosition[2];\r
+  Original[3]:=PatchPosition[3];\r
+  Original[4]:=PatchPosition[4];\r
+\r
+  {$ifdef MSWINDOWS}\r
+  if not VirtualProtect(Pointer(PatchPosition), 5, PAGE_EXECUTE_READWRITE, @ov) then\r
+    RaiseLastOSError;\r
+  {$endif}\r
+  {$ifdef LINUX}\r
+  pageSize:=sysconf (_SC_PAGE_SIZE);\r
+  p:=pointer(PatchPosition);\r
+  p:=pointer((integer(p) + PAGESIZE-1) and not (PAGESIZE-1) - pageSize);\r
+  if mprotect (p, pageSize, PROT_READ + PROT_WRITE + PROT_EXEC) <> 0 then\r
+    RaiseLastOSError;\r
+  {$endif}\r
+end;\r
+\r
+procedure THook.Shutdown;\r
+begin\r
+  Disable;\r
+  PatchPosition:=nil;\r
+end;\r
+\r
+procedure HookIntoResourceStrings (enabled:boolean=true; SupportPackages:boolean=false);\r
+begin\r
+  HookLoadResString.Reset (SupportPackages);\r
+  HookLoadStr.Reset (SupportPackages);\r
+  HookFmtLoadStr.Reset (SupportPackages);\r
+  if enabled then begin\r
+    HookLoadResString.Enable;\r
+    HookLoadStr.Enable;\r
+    HookFmtLoadStr.Enable;\r
+  end;\r
+end;\r
+\r
+{ TMoFile }\r
+\r
+function TMoFile.autoswap32(i: cardinal): cardinal;\r
+var\r
+  cnv1, cnv2:\r
+    record\r
+      case integer of\r
+        0: (arr: array[0..3] of byte);\r
+        1: (int: cardinal);\r
+    end;\r
+begin\r
+  if doswap then begin\r
+    cnv1.int := i;\r
+    cnv2.arr[0] := cnv1.arr[3];\r
+    cnv2.arr[1] := cnv1.arr[2];\r
+    cnv2.arr[2] := cnv1.arr[1];\r
+    cnv2.arr[3] := cnv1.arr[0];\r
+    Result := cnv2.int;\r
+  end else\r
+    Result := i;\r
+end;\r
+\r
+function TMoFile.CardinalInMem(baseptr: PChar; Offset: Cardinal): Cardinal;\r
+var pc:^Cardinal;\r
+begin\r
+  inc (baseptr,offset);\r
+  pc:=Pointer(baseptr);\r
+  Result:=pc^;\r
+  if doswap then\r
+    autoswap32(Result);\r
+end;\r
+\r
+constructor TMoFile.Create(filename: string; Offset,Size:int64);\r
+var\r
+  i:cardinal;\r
+  nn:integer;\r
+  {$ifdef linux}\r
+  mofile:TFileStream;\r
+  {$endif}\r
+begin\r
+  if sizeof(i) <> 4 then\r
+    raise EGGProgrammingError.Create('TDomain in gnugettext is written for an architecture that has 32 bit integers.');\r
+\r
+  {$ifdef mswindows}\r
+  // Map the mo file into memory and let the operating system decide how to cache\r
+  mo:=createfile (PChar(filename),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);\r
+  if mo=INVALID_HANDLE_VALUE then\r
+    raise EGGIOError.Create ('Cannot open file '+filename);\r
+  momapping:=CreateFileMapping (mo, nil, PAGE_READONLY, 0, 0, nil);\r
+  if momapping=0 then\r
+    raise EGGIOError.Create ('Cannot create memory map on file '+filename);\r
+  momemoryHandle:=MapViewOfFile (momapping,FILE_MAP_READ,0,0,0);\r
+  if momemoryHandle=nil then begin\r
+    raise EGGIOError.Create ('Cannot map file '+filename+' into memory. Reason: '+GetLastWinError);\r
+  end;\r
+  momemory:=momemoryHandle+offset;\r
+  {$endif}\r
+  {$ifdef linux}\r
+  // Read the whole file into memory\r
+  mofile:=TFileStream.Create (filename, fmOpenRead or fmShareDenyNone);\r
+  try\r
+    if size=0 then\r
+      size:=mofile.Size;\r
+    Getmem (momemoryHandle,size);\r
+    momemory:=momemoryHandle;\r
+    mofile.Seek(offset,soFromBeginning);\r
+    mofile.ReadBuffer(momemory^,size);\r
+  finally\r
+    FreeAndNil (mofile);\r
+  end;\r
+  {$endif}\r
+\r
+  // Check the magic number\r
+  doswap:=False;\r
+  i:=CardinalInMem(momemory,0);\r
+  if (i <> $950412DE) and (i <> $DE120495) then\r
+    EGGIOError.Create('This file is not a valid GNU gettext mo file: ' + filename);\r
+  doswap := (i = $DE120495);\r
+\r
+\r
+  // Find the positions in the file according to the file format spec\r
+  CardinalInMem(momemory,4);       // Read the version number, but don't use it for anything.\r
+  N:=CardinalInMem(momemory,8);    // Get string count\r
+  O:=CardinalInMem(momemory,12);   // Get offset of original strings\r
+  T:=CardinalInMem(momemory,16);   // Get offset of translated strings\r
+\r
+  // Calculate start conditions for a binary search\r
+  nn := N;\r
+  startindex := 1;\r
+  while nn <> 0 do begin\r
+    nn := nn shr 1;\r
+    startindex := startindex shl 1;\r
+  end;\r
+  startindex := startindex shr 1;\r
+  startstep := startindex shr 1;\r
+end;\r
+\r
+destructor TMoFile.Destroy;\r
+begin\r
+  {$ifdef mswindows}\r
+  UnMapViewOfFile (momemoryHandle);\r
+  CloseHandle (momapping);\r
+  CloseHandle (mo);\r
+  {$endif}\r
+  {$ifdef linux}\r
+  FreeMem (momemoryHandle);\r
+  {$endif}\r
+  inherited;\r
+end;\r
+\r
+function TMoFile.gettext(const msgid: ansistring;var found:boolean): ansistring;\r
+var\r
+  i, step: cardinal;\r
+  offset, pos: cardinal;\r
+  CompareResult:integer;\r
+  msgidptr,a,b:PChar;\r
+  abidx:integer;\r
+  size, msgidsize:integer;\r
+begin\r
+  found:=false;\r
+  msgidptr:=PChar(msgid);\r
+  msgidsize:=length(msgid);\r
+\r
+  // Do binary search\r
+  i:=startindex;\r
+  step:=startstep;\r
+  while true do begin\r
+    // Get string for index i\r
+    pos:=O+8*(i-1);\r
+    offset:=CardinalInMem (momemory,pos+4);\r
+    size:=CardinalInMem (momemory,pos);\r
+    a:=msgidptr;\r
+    b:=momemory+offset;\r
+    abidx:=size;\r
+    if msgidsize<abidx then\r
+      abidx:=msgidsize;\r
+    CompareResult:=0;\r
+    while abidx<>0 do begin\r
+      CompareResult:=integer(byte(a^))-integer(byte(b^));\r
+      if CompareResult<>0 then\r
+        break;\r
+      dec (abidx);\r
+      inc (a);\r
+      inc (b);\r
+    end;\r
+    if CompareResult=0 then \r
+      CompareResult:=msgidsize-size;\r
+    if CompareResult=0 then begin  // msgid=s\r
+      // Found the msgid\r
+      pos:=T+8*(i-1);\r
+      offset:=CardinalInMem (momemory,pos+4);\r
+      size:=CardinalInMem (momemory,pos);\r
+      SetString (Result,momemory+offset,size);\r
+      found:=True;\r
+      break;\r
+    end;\r
+    if step=0 then begin\r
+      // Not found\r
+      Result:=msgid;\r
+      break;\r
+    end;\r
+    if CompareResult<0 then begin  // msgid<s\r
+      if i < 1+step then\r
+        i := 1\r
+      else\r
+        i := i - step;\r
+      step := step shr 1;\r
+    end else begin  // msgid>s\r
+      i := i + step;\r
+      if i > N then\r
+        i := N;\r
+      step := step shr 1;\r
+    end;\r
+  end;\r
+end;\r
+\r
+// DELPHI4\r
+\r
+function GetPropInfo(Instance: TObject; const Name: string; var PropInfo: TPropInfo): Boolean;\r
+var\r
+  Props: PPropList;\r
+  TypeData: PTypeData;\r
+  Info: PPropInfo;\r
+  i: Integer;\r
+begin\r
+  TypeData := GetTypeData(Instance.ClassInfo);\r
+  if ((TypeData <> nil) and (TypeData^.PropCount > 0)) then\r
+  begin\r
+    GetMem(Props, TypeData^.PropCount * sizeof(Pointer));\r
+    try\r
+      GetPropInfos(Instance.ClassInfo, Props);\r
+      for i := 0 to TypeData.PropCount - 1 do\r
+      begin\r
+        Info := Props[i];\r
+        if (AnsiCompareText(Info.Name, Name) = 0) then\r
+        begin\r
+          PropInfo := Info^;\r
+          Result := True;\r
+          Exit;\r
+        end\r
+      end;\r
+    finally\r
+      FreeMem(Props);\r
+    end;\r
+  end;\r
+  Result := False;\r
+end;\r
+\r
+function GetStrProp(Instance: TObject; Info: PPropInfo): string;\r
+begin\r
+  Result := TypInfo.GetStrProp(Instance, Info);\r
+end;\r
+\r
+function GetStrProp(Instance: TObject; const Name: string): string;\r
+var\r
+  Info: TPropInfo;\r
+begin\r
+  if GetPropInfo(Instance, Name, Info) then\r
+    Result := TypInfo.GetStrProp(Instance, @Info)\r
+  else\r
+    Result := '';\r
+end;\r
+\r
+procedure SetStrProp(Instance: TObject; const Name, Value: string);\r
+var\r
+  Info: TPropInfo;\r
+begin\r
+  if GetPropInfo(Instance, Name, Info) then\r
+    SetStrProp(Instance, @Info, Value);\r
+end;\r
+\r
+procedure SetStrProp(Instance: TObject; Info: PPropInfo; const Value: string);\r
+begin\r
+  TypInfo.SetStrProp(Instance, Info, Value);\r
+end;\r
+\r
+initialization\r
+  {$ifdef DXGETTEXTDEBUG}\r
+  {$ifdef MSWINDOWS}\r
+  MessageBox (0,'gnugettext.pas debugging is enabled. Turn it off before releasing this piece of software.','Information',MB_OK);\r
+  {$endif}\r
+  {$ifdef LINUX}\r
+  writeln (stderr,'gnugettext.pas debugging is enabled. Turn it off before releasing this piece of software.');\r
+  {$endif}\r
+  {$endif}\r
+  if IsLibrary then begin\r
+    // Get DLL/shared object filename\r
+    SetLength (ExecutableFilename,300);\r
+    {$ifdef MSWINDOWS}\r
+    SetLength (ExecutableFilename,GetModuleFileName(HInstance, PChar(ExecutableFilename), length(ExecutableFilename)));\r
+    {$else}\r
+    // This line has not been tested on Linux, yet, but should work.\r
+    SetLength (ExecutableFilename,GetModuleFileName(0, PChar(ExecutableFilename), length(ExecutableFilename)));\r
+    {$endif}\r
+  end else\r
+    ExecutableFilename:=Paramstr(0);\r
+  FileLocator:=TFileLocator.Create;\r
+  FileLocator.Analyze;\r
+  ResourceStringDomainList:=TStringList.Create;\r
+  ResourceStringDomainList.Add(DefaultTextDomain);\r
+  ResourceStringDomainListCS:=TMultiReadExclusiveWriteSynchronizer.Create;\r
+  DefaultInstance:=TGnuGettextInstance.Create;\r
+  {$ifdef MSWINDOWS}\r
+  Win32PlatformIsUnicode := (Win32Platform = VER_PLATFORM_WIN32_NT);\r
+  {$endif}\r
+\r
+  // replace Borlands LoadResString with gettext enabled version:\r
+  HookLoadResString:=THook.Create (@system.LoadResString, @LoadResStringA);\r
+  HookLoadStr:=THook.Create (@sysutils.LoadStr, @SysUtilsLoadStr);\r
+  HookFmtLoadStr:=THook.Create (@sysutils.FmtLoadStr, @SysUtilsFmtLoadStr);\r
+  HookIntoResourceStrings (AutoCreateHooks,false);\r
+\r
+finalization\r
+  FreeAndNil (DefaultInstance);\r
+  FreeAndNil (ResourceStringDomainListCS);\r
+  FreeAndNil (ResourceStringDomainList);\r
+  FreeAndNil (HookFmtLoadStr);\r
+  FreeAndNil (HookLoadStr);\r
+  FreeAndNil (HookLoadResString);\r
+  FreeAndNil (FileLocator);\r
+\r
+end.\r
+\r
diff --git a/gpsbabel/win32/gui-2/gnugettextD4.pas b/gpsbabel/win32/gui-2/gnugettextD4.pas
new file mode 100644 (file)
index 0000000..1d98287
--- /dev/null
@@ -0,0 +1,292 @@
+unit gnugettextD4;\r
+(*  File version: $Date: 2005-09-28 00:33:08 $ *)\r
+(*  Revision: $Revision: 1.1 $ *)\r
+// Delphi 5 optimized interface for gnugettext.pas\r
+// This unit must only be used on Delphi 5. When you upgrade to Delphi 6 or\r
+// later, you should remove this unit and replace all reference to gnugettextD5\r
+// with refernces to gnugettext.\r
+\r
+interface\r
+\r
+uses\r
+  Classes;\r
+  \r
+// Ansistring versions of the api\r
+function _(const szMsgId: string): string;\r
+function gettext(const szMsgId: string): string;\r
+function dgettext(const szDomain: string; const szMsgId: string): string;\r
+procedure TranslateComponent(AnObject: TComponent);\r
+\r
+\r
+\r
+//*****************************************************************************\r
+// Don't use anything in the interface below this line.\r
+// It only contains code or gnugettext.pas to make it compile with Delphi 5.\r
+\r
+type\r
+  UTF8String = AnsiString;\r
+\r
+const\r
+  PathDelim='\';\r
+  sLineBreak=#13#10;\r
+\r
+function GetEnvironmentVariable(const VarName: string): string;\r
+function DirectoryExists(const Name:string):boolean;\r
+function IncludeTrailingPathDelimiter(s: string): string;\r
+function ExcludeTrailingPathDelimiter(s: string): string;\r
+procedure RaiseLastOSError;\r
+function StrToFloatDef(const S:String;Default:Extended):Extended;\r
+function Utf8Decode(const S: UTF8String): WideString;\r
+function Utf8Encode(const WS: WideString): UTF8String;\r
+\r
+// for delphi 4\r
+\r
+procedure FreeAndNil(var P);\r
+function IncludeTrailingBackSlash(const Path: string): string;\r
+function ExcludeTrailingBackslash(const Path: string): string;\r
+\r
+implementation\r
+\r
+uses\r
+  filectrl, Windows, SysUtils,\r
+  gnugettext;\r
+\r
+function GetEnvironmentVariable(const VarName: string): string;\r
+var Size: Integer;\r
+begin\r
+  Size := Windows.GetEnvironmentVariable(PChar(VarName), nil, 0);\r
+  SetLength(Result, Size - 1);\r
+  Windows.GetEnvironmentVariable(PChar(VarName), PChar(Result), Size);\r
+end;\r
+\r
+function DirectoryExists(const Name:string):boolean;\r
+begin\r
+  Result := FileCtrl.DirectoryExists(Name);\r
+end;\r
+\r
+function IncludeTrailingPathDelimiter(s: string): string;\r
+begin\r
+  Result := IncludeTrailingBackslash(s);\r
+end;\r
+\r
+function ExcludeTrailingPathDelimiter(s: string): string;\r
+begin\r
+  Result := ExcludeTrailingBackslash(s);\r
+end;\r
+\r
+procedure RaiseLastOSError;\r
+begin\r
+  RaiseLastWin32Error;\r
+end;\r
+\r
+function StrToFloatDef(const S:String;Default:Extended):Extended;\r
+begin\r
+  if not TextToFloat(PChar(S), Result, fvExtended) then\r
+    Result := Default;\r
+end;\r
+\r
+function UnicodeToUtf8(Dest: PChar; MaxDestBytes: Cardinal; Source: PWideChar; SourceChars: Cardinal): Cardinal;\r
+var\r
+  i, count: Cardinal;\r
+  c: Cardinal;\r
+begin\r
+  Result := 0;\r
+  if Source = nil then\r
+    Exit;\r
+  count := 0;\r
+  i := 0;\r
+  if Dest <> nil then begin\r
+    while (i < SourceChars) and (count < MaxDestBytes) do begin\r
+      c := Cardinal(Source[i]);\r
+      Inc(i);\r
+      if c <= $7F then begin\r
+        Dest[count] := Char(c);\r
+        Inc(count);\r
+      end else\r
+      if c > $7FF then begin\r
+        if count + 3 > MaxDestBytes then\r
+          break;\r
+        Dest[count] := Char($E0 or (c shr 12));\r
+        Dest[count + 1] := Char($80 or ((c shr 6) and $3F));\r
+        Dest[count + 2] := Char($80 or (c and $3F));\r
+        Inc(count, 3);\r
+      end else //  $7F < Source[i] <= $7FF\r
+      begin\r
+        if count + 2 > MaxDestBytes then\r
+          break;\r
+        Dest[count] := Char($C0 or (c shr 6));\r
+        Dest[count + 1] := Char($80 or (c and $3F));\r
+        Inc(count, 2);\r
+      end;\r
+    end;\r
+    if count >= MaxDestBytes then\r
+      count := MaxDestBytes - 1;\r
+    Dest[count] := #0;\r
+  end else begin\r
+    while i < SourceChars do begin\r
+      c := Integer(Source[i]);\r
+      Inc(i);\r
+      if c > $7F then begin\r
+        if c > $7FF then\r
+          Inc(count);\r
+        Inc(count);\r
+      end;\r
+      Inc(count);\r
+    end;\r
+  end;\r
+  Result := count + 1; // convert zero based index to byte count\r
+end;\r
+\r
+function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal;\r
+var\r
+  i, count: Cardinal;\r
+  c: Byte;\r
+  wc: Cardinal;\r
+begin\r
+  if Source = nil then begin\r
+    Result := 0;\r
+    Exit;\r
+  end;\r
+  Result := Cardinal(-1);\r
+  count := 0;\r
+  i := 0;\r
+  if Dest <> nil then begin\r
+    while (i < SourceBytes) and (count < MaxDestChars) do begin\r
+      wc := Cardinal(Source[i]);\r
+      Inc(i);\r
+      if (wc and $80) <> 0 then begin\r
+        if i >= SourceBytes then\r
+          Exit; // incomplete multibyte char\r
+        wc := wc and $3F;\r
+        if (wc and $20) <> 0 then begin\r
+          c := Byte(Source[i]);\r
+          Inc(i);\r
+          if (c and $C0) <> $80 then\r
+            Exit; // malformed trail byte or out of range char\r
+          if i >= SourceBytes then\r
+            Exit; // incomplete multibyte char\r
+          wc := (wc shl 6) or (c and $3F);\r
+        end;\r
+        c := Byte(Source[i]);\r
+        Inc(i);\r
+        if (c and $C0) <> $80 then\r
+          Exit; // malformed trail byte\r
+\r
+        Dest[count] := WideChar((wc shl 6) or (c and $3F));\r
+      end else\r
+        Dest[count] := WideChar(wc);\r
+      Inc(count);\r
+    end;\r
+    if count >= MaxDestChars then\r
+      count := MaxDestChars - 1;\r
+    Dest[count] := #0;\r
+  end else begin\r
+    while (i < SourceBytes) do begin\r
+      c := Byte(Source[i]);\r
+      Inc(i);\r
+      if (c and $80) <> 0 then begin\r
+        if i >= SourceBytes then\r
+          Exit; // incomplete multibyte char\r
+        c := c and $3F;\r
+        if (c and $20) <> 0 then begin\r
+          c := Byte(Source[i]);\r
+          Inc(i);\r
+          if (c and $C0) <> $80 then\r
+            Exit; // malformed trail byte or out of range char\r
+          if i >= SourceBytes then\r
+            Exit; // incomplete multibyte char\r
+        end;\r
+        c := Byte(Source[i]);\r
+        Inc(i);\r
+        if (c and $C0) <> $80 then\r
+          Exit; // malformed trail byte\r
+      end;\r
+      Inc(count);\r
+    end;\r
+  end;\r
+  Result := count + 1;\r
+end;\r
+\r
+function Utf8Decode(const S: UTF8String): WideString;\r
+var\r
+  L: Integer;\r
+  Temp: WideString;\r
+begin\r
+  Result := '';\r
+  if S = '' then\r
+    Exit;\r
+  SetLength(Temp, Length(S));\r
+\r
+  L := Utf8ToUnicode(PWideChar(Temp), Length(Temp) + 1, PChar(S), Length(S));\r
+  if L > 0 then\r
+    SetLength(Temp, L - 1)\r
+  else\r
+    Temp := '';\r
+  Result := Temp;\r
+end;\r
+\r
+function Utf8Encode(const WS: WideString): UTF8String;\r
+var\r
+  L: Integer;\r
+  Temp: UTF8String;\r
+begin\r
+  Result := '';\r
+  if WS = '' then\r
+    Exit;\r
+  SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator\r
+\r
+  L := UnicodeToUtf8(PChar(Temp), Length(Temp) + 1, PWideChar(WS), Length(WS));\r
+  if L > 0 then\r
+    SetLength(Temp, L - 1)\r
+  else\r
+    Temp := '';\r
+  Result := Temp;\r
+end;\r
+\r
+function _(const szMsgId: string): string;\r
+begin\r
+  Result:=gettext(szMsgid);\r
+end;\r
+\r
+function gettext(const szMsgId: string): string;\r
+begin\r
+  Result:=string(DefaultInstance.gettext(DefaultInstance.ansi2wide(szMsgId)));\r
+end;\r
+\r
+function dgettext(const szDomain: string; const szMsgId: string): string;\r
+begin\r
+  Result:=string(DefaultInstance.dgettext(szDomain,DefaultInstance.ansi2wide(szMsgId)));\r
+end;\r
+\r
+procedure TranslateComponent(AnObject: TComponent);\r
+begin\r
+  gnugettext.TranslateComponent(AnObject);\r
+end;\r
+\r
+// for delphi 4\r
+\r
+procedure FreeAndNil(var P);\r
+begin\r
+  TObject(P).Free;\r
+  Pointer(P) := NIL;\r
+end;\r
+\r
+function IncludeTrailingBackSlash(const Path: string): string;\r
+begin\r
+  if (Path <> '') and\r
+     not(Path[Length(Path)] in [':', '\']) then\r
+    Result := Path + '\'\r
+  else\r
+    Result := Path;\r
+end;\r
+\r
+function ExcludeTrailingBackslash(const Path: string): string;\r
+var\r
+  Len: Integer;\r
+begin\r
+  Len := Length(Path);\r
+  while (Len > 0) and (Path[Len] in ['/', '\']) do Dec(Len);\r
+  SetString(Result, PChar(Path), Len);\r
+end;\r
+\r
+end.\r
diff --git a/gpsbabel/win32/gui-2/locale/de/LC_MESSAGES/default.po b/gpsbabel/win32/gui-2/locale/de/LC_MESSAGES/default.po
new file mode 100644 (file)
index 0000000..c0b8bc0
--- /dev/null
@@ -0,0 +1,473 @@
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: GPSBabel 1.2.6\n"
+"POT-Creation-Date: 2005-08-12 14:50\n"
+"PO-Revision-Date: 2005-09-22 23:49+0100\n"
+"Last-Translator: Olaf Klein <o.b.klein@t-online.de>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: dxgettext 1.2\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
+
+#. frmAbout..Caption
+#: about.dfm:5
+msgid "About"
+msgstr "Über"
+
+#. frmAbout..Font.Name
+#. frmAbout..pnClient..StaticText1..Font.Name
+#. frmFilter..Font.Name
+#. frmMain..Font.Name
+#. frmMain..Panel2..lbWhat..Font.Name
+#. frmReadme..Font.Name
+#: about.dfm:12
+#: about.dfm:72
+#: filter.dfm:13
+#: main.dfm:11
+#: main.dfm:238
+#: readme.dfm:11
+msgid "MS Sans Serif"
+msgstr "MS Sans Serif"
+
+#. frmAbout..pnClient..Caption
+#: about.dfm:26
+msgid "... under construction"
+msgstr "... in Bearbeitung"
+
+#. frmAbout..pnClient..StaticText1..Caption
+#: about.dfm:68
+msgid "GPSBabelGUI-2:"
+msgstr "GPSBabelGUI-2:"
+
+#. frmAbout..pnClient..StaticText2..Caption
+#: about.dfm:82
+#, fuzzy
+msgid "The frontend for gpsbabel command line program"
+msgstr "Das Windows-Fontend für ..."
+
+#. frmFilter..Caption
+#: filter.dfm:6
+msgid "Filter"
+msgstr "Filter"
+
+#. frmFilter..gbTracks..Caption
+#. frmMain..Panel2..cbTracks..Caption
+#: filter.dfm:27
+#: main.dfm:393
+msgid "&Tracks"
+msgstr "&Tracks"
+
+#. frmFilter..gbTracks..lbTimePlusMinus..Caption
+#: filter.dfm:35
+msgid "by"
+msgstr "um"
+
+#. frmFilter..gbTracks..lbTimeDays..Caption
+#: filter.dfm:42
+msgid "day(s), "
+msgstr "Tag(e),"
+
+#. frmFilter..gbTracks..lbTimeHours..Caption
+#: filter.dfm:49
+msgid "hour(s), "
+msgstr "Stunde(n),"
+
+#. frmFilter..gbTracks..lbTimeMinutes..Caption
+#: filter.dfm:56
+msgid "minute(s),"
+msgstr "Minute(n),"
+
+#. frmFilter..gbTracks..lbTimeSeconds..Caption
+#: filter.dfm:63
+msgid "second(s)"
+msgstr "Sekunde(n)"
+
+#. frmFilter..gbTracks..cbTrackTitle..Hint
+#: filter.dfm:70
+msgid "Title for new tracks"
+msgstr "Titel für neu erstellte Tracks"
+
+#. frmFilter..gbTracks..cbTrackTitle..Caption
+#: filter.dfm:72
+msgid "Tit&le"
+msgstr "Tite&l"
+
+#. frmFilter..gbTracks..edTrackTitle..Text
+#: filter.dfm:84
+msgid "ACTIVE LOG # %Y%m%d"
+msgstr "ACTIVE LOG # %Y%m%d"
+
+#. frmFilter..gbTracks..cbTrackSplit..Hint
+#: filter.dfm:91
+msgid "Split track into several tracks depending on date of trackpoint"
+msgstr ""
+
+#. frmFilter..gbTracks..cbTrackSplit..Caption
+#: filter.dfm:92
+msgid "&Split"
+msgstr "&Splitten"
+
+#. frmFilter..gbTracks..cbTrackTime..Hint
+#: filter.dfm:100
+msgid "Shift all tracks"
+msgstr "Tracks um ein Zeiintervall verschieben "
+
+#. frmFilter..gbTracks..cbTrackTime..Caption
+#: filter.dfm:101
+msgid "&Move"
+msgstr "Verschieben"
+
+#. frmFilter..gbTracks..cbTrackStart..Hint
+#: filter.dfm:193
+msgid "Take only trackpoints starting at"
+msgstr "beginne bei Zeitpunkt ..."
+
+#. frmFilter..gbTracks..cbTrackStart..Caption
+#: filter.dfm:194
+msgid "Start at"
+msgstr "Beginnend am"
+
+#. frmFilter..gbTracks..cbTrackStop..Caption
+#: filter.dfm:234
+msgid "stop at"
+msgstr "bis zum"
+
+#. frmFilter..gbTracks..cbTrackPack..Hint
+#: filter.dfm:273
+msgid "Pack all tracks into one track (No duplicate timestamps)"
+msgstr "Alle Tracks zu einem einzigen zusammenfassen (doppelte Zeitstempel unzulässig)"
+
+#. frmFilter..gbTracks..cbTrackPack..Caption
+#: filter.dfm:274
+msgid "&Pack (or)"
+msgstr "&Packen (oder)"
+
+#. frmFilter..gbTracks..cbTrackMerge..Hint
+#: filter.dfm:283
+msgid "Merge all tracks into one track"
+msgstr ""
+
+#. frmFilter..gbTracks..cbTrackMerge..Caption
+#: filter.dfm:284
+msgid "Merge"
+msgstr "Zusammenführen"
+
+#. frmFilter..gbRoutes..Caption
+#: filter.dfm:295
+msgid "&Routes && Tracks"
+msgstr "&Routen && Tracks"
+
+#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption
+#: filter.dfm:303
+msgid "limit to"
+msgstr "maximal"
+
+#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption
+#: filter.dfm:311
+msgid "Points"
+msgstr "Punkte"
+
+#. frmFilter..gbRoutes..cbRouteSimplify..Hint
+#: filter.dfm:318
+msgid "Simplify routes and tracks by limited number of points"
+msgstr "Limitiert die Anzahl von Wegpunkten in Routen und Tracks"
+
+#. frmFilter..gbRoutes..cbRouteSimplify..Caption
+#: filter.dfm:319
+msgid "Simplify"
+msgstr "Vereinfachen"
+
+#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint
+#: filter.dfm:328
+msgid "Upper limit of points for routes and tracks"
+msgstr "Maximale Anzahl an Punkten innerhalb von Routen und Tracks"
+
+#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Text
+#: filter.dfm:333
+msgid "50 "
+msgstr "50 "
+
+#. frmFilter..gbRoutes..cbReverse..Hint
+#: filter.dfm:352
+msgid "Reverse routes and tracks"
+msgstr "Reihenfolge von Wegpunkten in Routen und Tracks umdrehen"
+
+#. frmFilter..gbRoutes..cbReverse..Caption
+#: filter.dfm:353
+msgid "Reverse"
+msgstr "Umdrehen"
+
+#. frmFilter..pnBottom..btnOK..Caption
+#: filter.dfm:370
+msgid "OK"
+msgstr "OK"
+
+#. frmFilter..pnBottom..BitBtn1..Caption
+#: filter.dfm:406
+msgid "File based filters"
+msgstr "Datei basierende Filter"
+
+#. frmFilter..gbWaypoints..Caption
+#. frmMain..Panel2..cbWaypoints..Caption
+#: filter.dfm:426
+#: main.dfm:373
+msgid "&Waypoints"
+msgstr "&Wegpunkte"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint
+#: filter.dfm:452
+msgid "Merge waypoints with duplicate locations"
+msgstr "Fasse Wegpunkte mit gleichen Koordinaten zusammen"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption
+#: filter.dfm:453
+msgid "locations"
+msgstr ""
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint
+#: filter.dfm:462
+msgid "Merge waypoints with duplicate \"short name\""
+msgstr "Fasse Wegpunkte mit gleichem Namen zusammen"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption
+#: filter.dfm:463
+msgid "\"short names\""
+msgstr "\"Kurznamen\""
+
+#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint
+#: filter.dfm:472
+#, fuzzy
+msgid "Merge waypoints separated by less then"
+msgstr ""
+
+#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption
+#: filter.dfm:473
+msgid "Radius"
+msgstr "Radius"
+
+#. frmFilter..gbWaypoints..cobWayptMergeDist....Items.Strings
+#: filter.dfm:487
+msgid "Feet"
+msgstr "Feet"
+
+#. frmFilter..gbWaypoints..cobWayptMergeDist....Items.Strings
+#: filter.dfm:488
+#: filter.pas:163
+msgid "Miles"
+msgstr "Miles"
+
+#. frmFilter..gbWaypoints..cbWayptSort..Hint
+#: filter.dfm:505
+msgid "Sort waypoints by \"short name\" or by description"
+msgstr "Sortiere Wegpunkte nach Name oder Beschreibung"
+
+#. frmFilter..gbWaypoints..cbWayptSort..Caption
+#: filter.dfm:506
+msgid "Sort"
+msgstr "Sortieren"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint
+#: filter.dfm:514
+msgid "Merge duplicate waypoints"
+msgstr "Entferne doppelte Wegpunkte"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption
+#: filter.dfm:515
+msgid "Duplicatates"
+msgstr "Duplikate"
+
+#. frmMain..Caption
+#: main.dfm:6
+msgid "GPSBabelGUI-2"
+msgstr "GPSBabelGUI-2"
+
+#. frmMain..Panel1..lbInputFile..Caption
+#: main.dfm:78
+msgid "&Input file"
+msgstr "Eingabe-Datei"
+
+#. frmMain..Panel1..lbOutputFile..Caption
+#: main.dfm:86
+msgid "Out&put file"
+msgstr "Ausgabe-Datei"
+
+#. frmMain..Panel1..lbInputFormat..Caption
+#: main.dfm:94
+msgid "Input &format"
+msgstr "Eingabe-Format"
+
+#. frmMain..Panel1..lbOutputFormat..Caption
+#: main.dfm:101
+msgid "Output f&ormat"
+msgstr "Ausgabe-Format"
+
+#. frmMain..Panel1..chbInputDevice..Caption
+#. frmMain..Panel1..chbOutputDevice..Caption
+#: main.dfm:150
+#: main.dfm:199
+msgid "Device"
+msgstr "Gerät"
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:162
+#: main.dfm:211
+msgid "USB"
+msgstr "USB"
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:163
+#: main.dfm:212
+msgid "COM1"
+msgstr "COM1"
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:164
+#: main.dfm:213
+msgid "COM2"
+msgstr "COM2"
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:165
+#: main.dfm:214
+msgid "COM3"
+msgstr "COM3"
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:166
+#: main.dfm:215
+msgid "COM4"
+msgstr "COM4"
+
+#. frmMain..Panel2..lbWhat..Caption
+#: main.dfm:234
+msgid "What ?"
+msgstr "Was?"
+
+#. frmMain..Panel2..cbRoutes..Caption
+#: main.dfm:384
+msgid "&Routes"
+msgstr "&Routen"
+
+#. frmMain..Panel2..btnFilter..Caption
+#. frmMain..ActionList1..acFilterSelect..Caption
+#: main.dfm:404
+#: main.dfm:907
+msgid "&Filter"
+msgstr "&Filter"
+
+#. frmMain..Panel2..btnProcess..Caption
+#. frmMain..ActionList1..acConvert..Caption
+#: main.dfm:428
+#: main.dfm:900
+msgid "let's go"
+msgstr "und los"
+
+#. frmMain..memoOutput..Font.Name
+#: main.dfm:455
+msgid "Fixedsys"
+msgstr "Fixedsys"
+
+#. frmMain..stbMain......Text
+#: main.dfm:473
+msgid "http://sourceforge.net/projects/gpsbabel"
+msgstr "http://sourceforge.net/projects/gpsbabel"
+
+#. frmMain..OpenDialog..Filter
+#: main.dfm:480
+msgid "Garmin Mapsource|*.gdb|Garmin Mapsource mps|*.mps|All files|*.*"
+msgstr "Garmin Mapsource|*.gdb|Garmin Mapsource mps|*.mps|All files|*.*"
+
+#. frmMain..ActionList1..acConvert..Category
+#. frmMain..ActionList1..acFilterSelect..Category
+#: main.dfm:899
+#: main.dfm:906
+msgid "Babel"
+msgstr "Babel"
+
+#. frmMain..ActionList1..acFileExit..Category
+#: main.dfm:912
+msgid "File"
+msgstr "Datei"
+
+#. frmMain..ActionList1..acFileExit..Caption
+#: main.dfm:913
+msgid "E&xit"
+msgstr "Beenden"
+
+#. frmMain..ActionList1..acHelpAbout..Category
+#. frmMain..ActionList1..acHelpIntro..Category
+#. frmMain..ActionList1..acHelpReadme..Category
+#: main.dfm:918
+#: main.dfm:923
+#: main.dfm:927
+msgid "Help"
+msgstr "Hilfe"
+
+#. frmMain..ActionList1..acHelpAbout..Caption
+#: main.dfm:919
+msgid "&About"
+msgstr "Über"
+
+#. frmMain..ActionList1..acHelpIntro..Caption
+#: main.dfm:924
+msgid "&Intro"
+msgstr "Einführung"
+
+#. frmMain..ActionList1..acHelpReadme..Caption
+#. frmReadme..Caption
+#: main.dfm:928
+#: readme.dfm:6
+msgid "GPSBabel README"
+msgstr "GPSBabel README"
+
+#. frmMain..MainMenu1..mnuFile..Caption
+#: main.dfm:937
+msgid "&File"
+msgstr "&Datei"
+
+#. frmMain..MainMenu1..mnuHelp..Caption
+#: main.dfm:943
+msgid "&Help"
+msgstr "&Hilfe"
+
+#: main.pas:249
+msgid "All files|*.*"
+msgstr "Alle Dateien|*.*"
+
+#: main.pas:338
+msgid "|All files|*.*"
+msgstr "|Alle Dateien|*.*"
+
+#: main.pas:377
+msgid "File %s not found."
+msgstr "Datei \"%s\" nicht gefunden."
+
+#: main.pas:394
+msgid "File \"%s\" exists ! Overwrite ?"
+msgstr "Datei \"%s\" existiert bereits! Ãœberschreiben?"
+
+#: main.pas:395
+msgid "Warning"
+msgstr "Warnung"
+
+#: main.pas:420
+msgid "Could not run \"gpsbabel.exe\"!"
+msgstr "Konnte \"gpsbabel.exe\" nicht ausführen!"
+
+#: main.pas:429
+msgid "Converted successfully from \"%s\" to \"%s\"."
+msgstr "Erfolgreich konvertiert von \"%s\" zu \"%s\"."
+
+#: main.pas:430
+msgid "Success"
+msgstr "Erfolg"
+
diff --git a/gpsbabel/win32/gui-2/locale/fr/LC_MESSAGES/default.po b/gpsbabel/win32/gui-2/locale/fr/LC_MESSAGES/default.po
new file mode 100644 (file)
index 0000000..5cdaafa
--- /dev/null
@@ -0,0 +1,476 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: French version\n"
+"POT-Creation-Date: 2005-09-22 23:44\n"
+"PO-Revision-Date: 2005-09-24 22:45+0100\n"
+"Last-Translator: Lilian Morinon <lilian_morinon@yahoo.fr>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: dxgettext 1.2\n"
+"Language-Team: Utagawa VTT <contact@utagawavtt.com>\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: FRANCE\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#. frmAbout..Caption
+#: about.dfm:5
+msgid "About"
+msgstr "A propos"
+
+#. frmAbout..Font.Name
+#. frmAbout..pnClient..StaticText1..Font.Name
+#. frmFilter..Font.Name
+#. frmMain..Font.Name
+#. frmMain..Panel2..lbWhat..Font.Name
+#. frmReadme..Font.Name
+#: about.dfm:12
+#: about.dfm:72
+#: filter.dfm:13
+#: main.dfm:11
+#: main.dfm:238
+#: readme.dfm:11
+msgid "MS Sans Serif"
+msgstr ""
+
+#. frmAbout..pnClient..Caption
+#: about.dfm:26
+msgid "... under construction"
+msgstr "...en travaux"
+
+#. frmAbout..pnClient..StaticText1..Caption
+#: about.dfm:68
+msgid "GPSBabelGUI-2:"
+msgstr ""
+
+#. frmAbout..pnClient..StaticText2..Caption
+#: about.dfm:82
+msgid "The frontend for gpsbabel command line program"
+msgstr "L'interface graphique de gpsbabel"
+
+#. frmFilter..Caption
+#: filter.dfm:6
+msgid "Filter"
+msgstr "Filtre"
+
+#. frmFilter..gbTracks..Caption
+#. frmMain..Panel2..cbTracks..Caption
+#: filter.dfm:27
+#: main.dfm:393
+msgid "&Tracks"
+msgstr "&Traces"
+
+#. frmFilter..gbTracks..lbTimePlusMinus..Caption
+#: filter.dfm:35
+msgid "by"
+msgstr "par"
+
+#. frmFilter..gbTracks..lbTimeDays..Caption
+#: filter.dfm:42
+msgid "day(s), "
+msgstr "jour(s),"
+
+#. frmFilter..gbTracks..lbTimeHours..Caption
+#: filter.dfm:49
+msgid "hour(s), "
+msgstr "heure(s)"
+
+#. frmFilter..gbTracks..lbTimeMinutes..Caption
+#: filter.dfm:56
+msgid "minute(s),"
+msgstr "minute(s)"
+
+#. frmFilter..gbTracks..lbTimeSeconds..Caption
+#: filter.dfm:63
+msgid "second(s)"
+msgstr "seconde(s)"
+
+#. frmFilter..gbTracks..cbTrackTitle..Hint
+#: filter.dfm:70
+msgid "Title for new tracks"
+msgstr "Titres des nouvelles traces"
+
+#. frmFilter..gbTracks..cbTrackTitle..Caption
+#: filter.dfm:72
+msgid "Tit&le"
+msgstr "Tit&re"
+
+#. frmFilter..gbTracks..edTrackTitle..Text
+#: filter.dfm:84
+msgid "ACTIVE LOG # %Y%m%d"
+msgstr ""
+
+#. frmFilter..gbTracks..cbTrackSplit..Hint
+#: filter.dfm:91
+msgid "Split track into several tracks depending on date of trackpoint"
+msgstr "Scinder la trace en plusieurs traces en fonction de la date des points"
+
+#. frmFilter..gbTracks..cbTrackSplit..Caption
+#: filter.dfm:92
+msgid "&Split"
+msgstr "&Scinder"
+
+#. frmFilter..gbTracks..cbTrackTime..Hint
+#: filter.dfm:100
+msgid "Shift all tracks"
+msgstr "Inverser toutes les traces"
+
+#. frmFilter..gbTracks..cbTrackTime..Caption
+#: filter.dfm:101
+msgid "&Move"
+msgstr "&Déplacer"
+
+#. frmFilter..gbTracks..cbTrackStart..Hint
+#: filter.dfm:193
+msgid "Take only trackpoints starting at"
+msgstr "Utiliser seulement les points commençant Ã "
+
+#. frmFilter..gbTracks..cbTrackStart..Caption
+#: filter.dfm:194
+msgid "Start at"
+msgstr "Commencer Ã "
+
+#. frmFilter..gbTracks..cbTrackStop..Caption
+#: filter.dfm:234
+msgid "stop at"
+msgstr "Arrêter Ã "
+
+#. frmFilter..gbTracks..cbTrackPack..Hint
+#: filter.dfm:273
+msgid "Pack all tracks into one track (No duplicate timestamps)"
+msgstr "Fusionner toutes les traces en une seule (pas de duplication de l'horodatage)"
+
+#. frmFilter..gbTracks..cbTrackPack..Caption
+#: filter.dfm:274
+msgid "&Pack (or)"
+msgstr "&Fusionner (ou)"
+
+#. frmFilter..gbTracks..cbTrackMerge..Hint
+#: filter.dfm:283
+msgid "Merge all tracks into one track"
+msgstr "Fusionner toutes les traces en une seule"
+
+#. frmFilter..gbTracks..cbTrackMerge..Caption
+#: filter.dfm:284
+msgid "Merge"
+msgstr "Fusionner"
+
+#. frmFilter..gbRoutes..Caption
+#: filter.dfm:295
+msgid "&Routes && Tracks"
+msgstr "&Routes && Traces"
+
+#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption
+#: filter.dfm:303
+msgid "limit to"
+msgstr "limiter Ã "
+
+#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption
+#: filter.dfm:311
+msgid "Points"
+msgstr ""
+
+#. frmFilter..gbRoutes..cbRouteSimplify..Hint
+#: filter.dfm:318
+msgid "Simplify routes and tracks by limited number of points"
+msgstr "Simplifier les routes et traces en limitant le nombre de points"
+
+#. frmFilter..gbRoutes..cbRouteSimplify..Caption
+#: filter.dfm:319
+msgid "Simplify"
+msgstr "Simplifier"
+
+#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint
+#: filter.dfm:328
+msgid "Upper limit of points for routes and tracks"
+msgstr "Limite maximum du nombre de points pour les routes et traces"
+
+#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Text
+#: filter.dfm:333
+msgid "50 "
+msgstr ""
+
+#. frmFilter..gbRoutes..cbReverse..Hint
+#: filter.dfm:352
+msgid "Reverse routes and tracks"
+msgstr "Inverser les routes et les traces"
+
+#. frmFilter..gbRoutes..cbReverse..Caption
+#: filter.dfm:353
+msgid "Reverse"
+msgstr "Inverser"
+
+#. frmFilter..pnBottom..btnOK..Caption
+#: filter.dfm:370
+msgid "OK"
+msgstr ""
+
+#. frmFilter..pnBottom..BitBtn1..Caption
+#: filter.dfm:406
+msgid "File based filters"
+msgstr "Filtres de fichiers"
+
+#. frmFilter..gbWaypoints..Caption
+#. frmMain..Panel2..cbWaypoints..Caption
+#: filter.dfm:426
+#: main.dfm:373
+msgid "&Waypoints"
+msgstr ""
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint
+#: filter.dfm:452
+msgid "Merge waypoints with duplicate locations"
+msgstr "Fusionner les waypoints avec les positions en doublon"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption
+#: filter.dfm:453
+msgid "locations"
+msgstr "positions"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint
+#: filter.dfm:462
+msgid "Merge waypoints with duplicate \"short name\""
+msgstr "Fusionner les waypoints avec les doublons \"short name\""
+
+#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption
+#: filter.dfm:463
+msgid "\"short names\""
+msgstr ""
+
+#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint
+#: filter.dfm:472
+msgid "Merge waypoints separated by less then"
+msgstr "Fusionner les waypoints séparé par moins de"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption
+#: filter.dfm:473
+msgid "Radius"
+msgstr "Rayon"
+
+#. frmFilter..gbWaypoints..cobWayptMergeDist....Items.Strings
+#: filter.dfm:487
+msgid "Feet"
+msgstr ""
+
+#. frmFilter..gbWaypoints..cobWayptMergeDist....Items.Strings
+#: filter.dfm:488
+#: filter.pas:163
+msgid "Miles"
+msgstr ""
+
+#. frmFilter..gbWaypoints..cbWayptSort..Hint
+#: filter.dfm:505
+msgid "Sort waypoints by \"short name\" or by description"
+msgstr "Trier les waypoints par \"short name\" ou par description"
+
+#. frmFilter..gbWaypoints..cbWayptSort..Caption
+#: filter.dfm:506
+msgid "Sort"
+msgstr "Trier"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint
+#: filter.dfm:514
+msgid "Merge duplicate waypoints"
+msgstr "Fusionner les waypoints identiques"
+
+#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption
+#: filter.dfm:515
+msgid "Duplicatates"
+msgstr "Doublons"
+
+#. frmMain..Caption
+#: main.dfm:6
+msgid "GPSBabelGUI-2"
+msgstr ""
+
+#. frmMain..Panel1..lbInputFile..Caption
+#: main.dfm:78
+msgid "&Input file"
+msgstr "Fichier &source"
+
+#. frmMain..Panel1..lbOutputFile..Caption
+#: main.dfm:86
+msgid "Out&put file"
+msgstr "Fichier &cible"
+
+#. frmMain..Panel1..lbInputFormat..Caption
+#: main.dfm:94
+msgid "Input &format"
+msgstr "Format sou&rce"
+
+#. frmMain..Panel1..lbOutputFormat..Caption
+#: main.dfm:101
+msgid "Output f&ormat"
+msgstr "Format ci&ble"
+
+#. frmMain..Panel1..chbInputDevice..Caption
+#. frmMain..Panel1..chbOutputDevice..Caption
+#: main.dfm:150
+#: main.dfm:199
+msgid "Device"
+msgstr "Périphérique"
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:162
+#: main.dfm:211
+msgid "USB"
+msgstr ""
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:163
+#: main.dfm:212
+msgid "COM1"
+msgstr ""
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:164
+#: main.dfm:213
+msgid "COM2"
+msgstr ""
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:165
+#: main.dfm:214
+msgid "COM3"
+msgstr ""
+
+#. frmMain..Panel1..cbInputDevice....Items.Strings
+#. frmMain..Panel1..cbOutputDevice....Items.Strings
+#: main.dfm:166
+#: main.dfm:215
+msgid "COM4"
+msgstr ""
+
+#. frmMain..Panel2..lbWhat..Caption
+#: main.dfm:234
+msgid "What ?"
+msgstr "Quoi ?"
+
+#. frmMain..Panel2..cbRoutes..Caption
+#: main.dfm:384
+msgid "&Routes"
+msgstr ""
+
+#. frmMain..Panel2..btnFilter..Caption
+#. frmMain..ActionList1..acFilterSelect..Caption
+#: main.dfm:404
+#: main.dfm:907
+msgid "&Filter"
+msgstr "&Filtre"
+
+#. frmMain..Panel2..btnProcess..Caption
+#. frmMain..ActionList1..acConvert..Caption
+#: main.dfm:428
+#: main.dfm:900
+msgid "let's go"
+msgstr "Lancer"
+
+#. frmMain..memoOutput..Font.Name
+#: main.dfm:455
+msgid "Fixedsys"
+msgstr ""
+
+#. frmMain..stbMain......Text
+#: main.dfm:473
+msgid "http://sourceforge.net/projects/gpsbabel"
+msgstr ""
+
+#. frmMain..OpenDialog..Filter
+#: main.dfm:480
+msgid "Garmin Mapsource|*.gdb|Garmin Mapsource mps|*.mps|All files|*.*"
+msgstr "Garmin Mapsource|*.gdb|Garmin Mapsource mps|*.mps|Tous les fichiers|*.*"
+
+#. frmMain..ActionList1..acConvert..Category
+#. frmMain..ActionList1..acFilterSelect..Category
+#: main.dfm:899
+#: main.dfm:906
+msgid "Babel"
+msgstr ""
+
+#. frmMain..ActionList1..acFileExit..Category
+#: main.dfm:912
+msgid "File"
+msgstr "Fichier"
+
+#. frmMain..ActionList1..acFileExit..Caption
+#: main.dfm:913
+msgid "E&xit"
+msgstr "F&ermer"
+
+#. frmMain..ActionList1..acHelpAbout..Category
+#. frmMain..ActionList1..acHelpIntro..Category
+#. frmMain..ActionList1..acHelpReadme..Category
+#: main.dfm:918
+#: main.dfm:923
+#: main.dfm:927
+msgid "Help"
+msgstr "Aide"
+
+#. frmMain..ActionList1..acHelpAbout..Caption
+#: main.dfm:919
+msgid "&About"
+msgstr "&A propos"
+
+#. frmMain..ActionList1..acHelpIntro..Caption
+#: main.dfm:924
+msgid "&Intro"
+msgstr "&Introduction"
+
+#. frmMain..ActionList1..acHelpReadme..Caption
+#. frmReadme..Caption
+#: main.dfm:928
+#: readme.dfm:6
+msgid "GPSBabel README"
+msgstr "GPSBabel README"
+
+#. frmMain..MainMenu1..mnuFile..Caption
+#: main.dfm:937
+msgid "&File"
+msgstr "&Fichier"
+
+#. frmMain..MainMenu1..mnuHelp..Caption
+#: main.dfm:943
+msgid "&Help"
+msgstr "&Aide"
+
+#: main.pas:249
+msgid "All files|*.*"
+msgstr "Tous les fichiers|*.*"
+
+#: main.pas:338
+msgid "|All files|*.*"
+msgstr "|Tous les fichiers|*.*"
+
+#: main.pas:377
+msgid "File %s not found."
+msgstr "Fichier%s non trouvé."
+
+#: main.pas:394
+msgid "File \"%s\" exists ! Overwrite ?"
+msgstr "Le fichier \"%s\" existe déjà ! Ecraser ?"
+
+#: main.pas:395
+msgid "Warning"
+msgstr "Attention"
+
+#: main.pas:420
+msgid "Could not run \"gpsbabel.exe\"!"
+msgstr "Impossible d'éxécuter \"gpsbabel.exe\"!"
+
+#: main.pas:429
+msgid "Converted successfully from \"%s\" to \"%s\"."
+msgstr "Conversion de \"%s\" Ã  \"%s\" réussie."
+
+#: main.pas:430
+msgid "Success"
+msgstr "Succès"
+
diff --git a/gpsbabel/win32/gui-2/main.dfm b/gpsbabel/win32/gui-2/main.dfm
new file mode 100644 (file)
index 0000000..3291100
Binary files /dev/null and b/gpsbabel/win32/gui-2/main.dfm differ
diff --git a/gpsbabel/win32/gui-2/main.pas b/gpsbabel/win32/gui-2/main.pas
new file mode 100644 (file)
index 0000000..e909f5d
--- /dev/null
@@ -0,0 +1,570 @@
+unit main;\r
+\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+interface\r
+\r
+uses\r
+  gnugettextD4,\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  StdCtrls, Buttons, ExtCtrls,\r
+  common, utils, ImgList, ActnList, Menus, ComCtrls;\r
+\r
+type\r
+  TfrmMain = class(TForm)\r
+    Panel1: TPanel;\r
+    sbOpenFile: TSpeedButton;\r
+    cbInputFormat: TComboBox;\r
+    cbOutputFormat: TComboBox;\r
+    edOutputFile: TEdit;\r
+    sbSaveFile: TSpeedButton;\r
+    lbInputFile: TLabel;\r
+    lbOutputFile: TLabel;\r
+    lbInputFormat: TLabel;\r
+    lbOutputFormat: TLabel;\r
+    edInputFile: TEdit;\r
+    Panel2: TPanel;\r
+    cbWaypoints: TCheckBox;\r
+    cbRoutes: TCheckBox;\r
+    cbTracks: TCheckBox;\r
+    lbWhat: TLabel;\r
+    OpenDialog: TOpenDialog;\r
+    SaveDialog: TSaveDialog;\r
+    wptInputOK: TSpeedButton;\r
+    ImageList1: TImageList;\r
+    wptOutputOK: TSpeedButton;\r
+    rteInputOK: TSpeedButton;\r
+    rteOutputOK: TSpeedButton;\r
+    trkInputOK: TSpeedButton;\r
+    trkOutputOK: TSpeedButton;\r
+    ActionList1: TActionList;\r
+    acConvert: TAction;\r
+    btnFilter: TBitBtn;\r
+    acFilterSelect: TAction;\r
+    btnProcess: TBitBtn;\r
+    memoOutput: TMemo;\r
+    stbMain: TStatusBar;\r
+    MainMenu1: TMainMenu;\r
+    mnuFile: TMenuItem;\r
+    mnuExit: TMenuItem;\r
+    acFileExit: TAction;\r
+    mnuHelp: TMenuItem;\r
+    acHelpAbout: TAction;\r
+    acHelpIntro: TAction;\r
+    Intro1: TMenuItem;\r
+    About1: TMenuItem;\r
+    chbInputDevice: TCheckBox;\r
+    cbInputDevice: TComboBox;\r
+    cbInputFormatDevice: TComboBox;\r
+    cbOutputFormatDevice: TComboBox;\r
+    chbOutputDevice: TCheckBox;\r
+    cbOutputDevice: TComboBox;\r
+    mnuReadme: TMenuItem;\r
+    acHelpReadme: TAction;\r
+    N1: TMenuItem;\r
+    procedure FormShow(Sender: TObject);\r
+    procedure FormCreate(Sender: TObject);\r
+    procedure OpenButtonClick(Sender: TObject);\r
+    procedure ComboChange(Sender: TObject);\r
+    procedure edInputFileChange(Sender: TObject);\r
+    procedure CheckInput;\r
+    procedure edOutputFileChange(Sender: TObject);\r
+    procedure cbWaypointsClick(Sender: TObject);\r
+    procedure cbRoutesClick(Sender: TObject);\r
+    procedure cbTracksClick(Sender: TObject);\r
+    procedure sbSaveFileClick(Sender: TObject);\r
+    procedure acConvertExecute(Sender: TObject);\r
+    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);\r
+    procedure acFilterSelectExecute(Sender: TObject);\r
+    procedure acFileExitExecute(Sender: TObject);\r
+    procedure acHelpAboutExecute(Sender: TObject);\r
+    procedure chbInputDeviceClick(Sender: TObject);\r
+    procedure FormClose(Sender: TObject; var Action: TCloseAction);\r
+    procedure chbOutputDeviceClick(Sender: TObject);\r
+    procedure acHelpReadmeExecute(Sender: TObject);\r
+  private\r
+    { Private-Deklarationen }\r
+    FCaps: TCapabilities;\r
+    FFirstShow: Boolean;\r
+    procedure AddToOutput(const Str: string);\r
+    procedure AddToOutputFmt(const Format: string; const Args: array of const);\r
+    procedure InitCombo(Target: TComboBox; ForRead, ForDevice: Boolean);\r
+    procedure LoadFileFormats;\r
+    procedure LoadVersion;\r
+    procedure WMSTARTUP(var Msg: TMessage); message WM_STARTUP;\r
+    procedure StoreProfiles;\r
+  public\r
+    { Public-Deklarationen }\r
+  end;\r
+\r
+var\r
+  frmMain: TfrmMain;\r
+\r
+implementation\r
+\r
+uses filter, about, readme;\r
+\r
+{$R *.DFM}\r
+\r
+procedure FixAlign(Control: TControl; ShiftLeft: Integer;\r
+  RightOfMe: TControl = nil);\r
+var\r
+  Right: Integer;\r
+begin\r
+  Right := Control.Parent.Left + Control.Parent.Width;\r
+\r
+  if Assigned(RightOfMe) then\r
+    ShiftLeft := ShiftLeft + RightOfMe.Width;\r
+\r
+  if (akLeft in Control.Anchors) then\r
+    Control.Width := Right - Control.Left - ShiftLeft\r
+  else if (akRight in Control.Anchors) then\r
+    Control.Left := Right - Control.Width - ShiftLeft;\r
+end;\r
+\r
+{ TfrmMain }\r
+\r
+procedure TfrmMain.FormCreate(Sender: TObject);\r
+var\r
+  s: string;\r
+begin\r
+  gnugettextD4.TranslateComponent(SELF);\r
+\r
+  Caption := Caption + _(' (Preview)');\r
+\r
+  FCaps := TCapabilities.Create;\r
+\r
+  OpenDialog.InitialDir := ReadProfile(OpenDialog.Tag);\r
+  SaveDialog.InitialDir := ReadProfile(SaveDialog.Tag);\r
+\r
+  s := ReadProfile(cbInputDevice.Tag);\r
+  if (s <> '') then\r
+    cbInputDevice.Text := s\r
+  else\r
+    cbInputDevice.ItemIndex := 0;\r
+\r
+  s := ReadProfile(cbOutputDevice.Tag);\r
+  if (s <> '') then\r
+    cbOutputDevice.Text := s\r
+  else\r
+    cbOutputDevice.ItemIndex := 0;\r
+\r
+  FFirstShow := True;\r
+\r
+  FixAlign(sbOpenFile, 8);\r
+  FixAlign(sbSaveFile, 8);\r
+  FixAlign(cbInputFormat, 8);\r
+  FixAlign(cbInputFormatDevice, 8);\r
+  FixAlign(cbOutputFormat, 8);\r
+  FixAlign(btnProcess, 8);\r
+  FixAlign(btnFilter, 16, btnProcess);\r
+  FixAlign(edInputFile, 8, sbOpenFile);\r
+  FixAlign(edOutputFile, 8, sbSaveFile);\r
+  FixAlign(cbOutputFormatDevice, 8);\r
+end;\r
+\r
+procedure TfrmMain.LoadFileFormats;\r
+var\r
+  l: TStrings;\r
+begin\r
+  l := TStringList.Create;\r
+  try\r
+    gpsbabel('-^2', l);\r
+    FCaps.List := l;\r
+    InitCombo(cbInputFormat, True, False);\r
+    InitCombo(cbOutputFormat, False, False);\r
+    InitCombo(cbInputFormatDevice, False, True);\r
+    InitCombo(cbOutputFormatDevice, True, True);\r
+  finally\r
+    l.Free;\r
+  end;\r
+end;\r
+\r
+procedure TfrmMain.FormShow(Sender: TObject);\r
+begin\r
+  if not(FFirstShow) then Exit;\r
+  FFirstShow := False;\r
+  PostMessage(SELF.Handle, WM_STARTUP, 0, 0); // keep sure our window is visible\r
+end;\r
+\r
+procedure TfrmMain.WMSTARTUP(var Msg: TMessage);\r
+begin\r
+  LoadVersion;\r
+  LoadFileFormats;\r
+  \r
+  // README form\r
+\r
+  acHelpReadme.Enabled := (frmReadme.Memo.Lines.Count > 0);\r
+end;\r
+\r
+procedure TfrmMain.InitCombo(Target: TComboBox; ForRead, ForDevice: Boolean);\r
+var\r
+  i: Integer;\r
+  OK: Boolean;\r
+  s: string;\r
+begin\r
+  for i := 0 to FCaps.Count - 1 do\r
+  begin\r
+    if (ForDevice and not(FCaps.IsDevice(i))) then Continue;\r
+    if not(ForDevice) and not FCaps.IsFile(i) then Continue;\r
+\r
+    if (ForRead) then\r
+      OK := FCaps.CanReadAny(i)\r
+    else\r
+      OK := FCaps.CanWriteAny(i);\r
+    if OK then\r
+      Target.Items.Add(FCaps.GetDescr(i));\r
+  end;\r
+\r
+  s := ReadProfile(Target.Tag);\r
+\r
+  i := FCaps.GetCaps(s);\r
+  if (i > 0) then\r
+    Target.Text := s;\r
+  ComboChange(Target);\r
+end;\r
+\r
+procedure TfrmMain.OpenButtonClick(Sender: TObject);\r
+var\r
+  s: string;\r
+begin\r
+  OpenDialog.Filter := '';\r
+  OpenDialog.DefaultExt := '*.*';\r
+\r
+  if (cbInputFormat.Text <> '') then\r
+    s := cbInputFormat.Text + '|*.' + FCaps.GetExt(cbInputFormat.Text) + '|';\r
+  s := s + _('All files|*.*');\r
+\r
+  OpenDialog.Filter := s;\r
+  if not SELF.OpenDialog.Execute then Exit;\r
+\r
+  edInputFile.Text := OpenDialog.FileName;\r
+end;\r
+\r
+procedure TfrmMain.ComboChange(Sender: TObject);\r
+var\r
+  caps: Integer;\r
+  ext: string;\r
+begin\r
+  caps := FCaps.GetCaps(TComboBox(Sender).Text);\r
+  ext := FCaps.GetExt(TComboBox(Sender).Text);\r
+\r
+  if (Sender = cbInputFormat) then\r
+  begin\r
+    wptInputOK.Enabled := (caps and 1 <> 0);\r
+    trkInputOK.Enabled := (caps and 4 <> 0);\r
+    rteInputOK.Enabled := (caps and 16 <> 0);\r
+  end\r
+    else\r
+  begin\r
+    wptOutputOK.Enabled := (caps and 2 <> 0);\r
+    trkOutputOK.Enabled := (caps and 8 <> 0);\r
+    rteOutputOK.Enabled := (caps and 32 <> 0);\r
+    if (edOutputFile.Text <> '') and (ext <> '') then\r
+    begin\r
+      edOutputFile.Text := SysUtils.ChangeFileExt(edOutputFile.Text, '.' + ext);\r
+    end;\r
+  end;\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.edInputFileChange(Sender: TObject);\r
+begin\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.CheckInput;\r
+begin\r
+  acConvert.Enabled :=\r
+    ((chbInputDevice.Checked and\r
+    (cbInputDevice.Text <> '') and\r
+    (cbInputFormatDevice.Text <> ''))\r
+  or\r
+    (not(chbInputDevice.Checked) and\r
+    (edInputFile.Text <> '') and\r
+    (cbInputFormat.Text <> '')))\r
+  and\r
+    ((chbOutputDevice.Checked and\r
+    (cbOutputDevice.Text <> '') and\r
+    (cbOutputFormatDevice.Text <> ''))\r
+  or\r
+    (not(chbOutputDevice.Checked) and\r
+    (edOutputFile.Text <> '') and\r
+    (cbOutputFormat.Text <> '')));\r
+end;\r
+\r
+procedure TfrmMain.edOutputFileChange(Sender: TObject);\r
+begin\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.cbWaypointsClick(Sender: TObject);\r
+begin\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.cbRoutesClick(Sender: TObject);\r
+begin\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.cbTracksClick(Sender: TObject);\r
+begin\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.sbSaveFileClick(Sender: TObject);\r
+var\r
+  s: string;\r
+begin\r
+  SaveDialog.Filter := '';\r
+  SaveDialog.DefaultExt := '*.*';\r
+\r
+  if (cbOutputFormat.Text <> '') then\r
+    s := cbOutputFormat.Text + '|*.' + FCaps.GetExt(cbOutputFormat.Text) + '|';\r
+  s := s + _('|All files|*.*');\r
+\r
+  SaveDialog.Filter := s;\r
+  if not SELF.SaveDialog.Execute then Exit;\r
+\r
+  edOutputFile.Text := SaveDialog.FileName;\r
+end;\r
+\r
+procedure TfrmMain.acConvertExecute(Sender: TObject);\r
+var\r
+  cmdline: string;\r
+  list: TStrings;\r
+  CSave: TCursor;\r
+  str: TStream;\r
+  s: string;\r
+  i: Integer;\r
+  IFormat, OFormat: string;\r
+\r
+begin\r
+  cmdline := '';\r
+\r
+  if chbInputDevice.Checked then\r
+    IFormat := FCaps.GetName(cbInputFormatDevice.Text)\r
+  else\r
+    IFormat := FCaps.GetName(cbInputFormat.Text);\r
+  if chbOutputDevice.Checked then\r
+    OFormat := FCaps.GetName(cbOutputFormatDevice.Text)\r
+  else\r
+    OFormat := FCaps.GetName(cbOutputFormat.Text);\r
+\r
+  if cbWaypoints.Checked then cmdline := cmdline + ' -w';\r
+  if cbRoutes.Checked then cmdline := cmdline + ' -r';\r
+  if cbTracks.Checked then cmdline := cmdline + ' -t';\r
+\r
+  if chbInputDevice.Checked then\r
+    s := SysUtils.AnsiLowerCase(cbInputDevice.Text) + ':'\r
+  else begin\r
+    s := edInputFile.Text;\r
+    if not(FileExists(s)) then\r
+    raise eGPSBabelError.CreateFmt(_('File %s not found.'), [s]);\r
+    s := '"' + s + '"';\r
+  end;\r
+\r
+  cmdline := Format('%s -i %s -f %s',\r
+    [ cmdline, IFormat, s]);\r
+\r
+  cmdline := cmdline + frmFilter.CmdLine;\r
+\r
+  if (chbOutputDevice.Checked) then\r
+    s := cbOutputDevice.Text + ':'\r
+  else begin\r
+    s := edOutputFile.Text;\r
+\r
+    if FileExists(s) then\r
+    begin\r
+      if (Windows.MessageBox(SELF.Handle,\r
+        PChar(Format(_('File "%s" exists ! Overwrite ?'), [s])),\r
+        PChar(_('Warning')), MB_YESNO) <> IDYES) then Exit;\r
+    end\r
+      else\r
+    begin\r
+      str := TFileStream.Create(s, fmCreate);\r
+      str.Free;\r
+    end;\r
+    s := '"' + s + '"';\r
+  end;\r
+\r
+  cmdline := Format('%s -o %s -F %s',\r
+    [ cmdline, OFormat, s]);\r
+\r
+  while (cmdline[1] = ' ') do System.Delete(cmdline, 1, 1);\r
+\r
+  AddToOutput('gpsbabel.exe ' + cmdline);\r
+\r
+  list := TStringList.Create;\r
+  try\r
+    CSave := Cursor;\r
+    Cursor := crHourGlass;\r
+    Application.ProcessMessages;\r
+    Sleep(50);\r
+\r
+    if not gpsbabel(cmdline, list) then\r
+      raise eGPSBabelError.Create(_('Could not run "gpsbabel.exe"!'));\r
+\r
+    if (list.Count > 0) then\r
+    begin\r
+      AddToOutput('');\r
+      AddToOutput(string(list.GetText));\r
+    end;\r
+\r
+    MessageBox(SELF.Handle,\r
+      PChar(Format(_('Converted successfully from "%s" to "%s".'), [IFormat, OFormat])),\r
+      PChar(_('Success')), MB_OK);\r
+\r
+  finally\r
+\r
+    Cursor := CSave;\r
+    list.Free;\r
+\r
+  end;\r
+end;\r
+\r
+procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);\r
+begin\r
+  CanClose := True;\r
+end;\r
+\r
+procedure TfrmMain.acFilterSelectExecute(Sender: TObject);\r
+begin\r
+  if not(frmFilter.ShowModal = mrOk) then Exit;\r
+end;\r
+\r
+procedure TfrmMain.AddToOutput(const Str: string);\r
+begin\r
+  memoOutput.Lines.Add(Str);\r
+end;\r
+\r
+procedure TfrmMain.AddToOutputFmt(const Format: string;\r
+  const Args: array of const);\r
+begin\r
+  AddToOutput(SysUtils.Format(Format, Args));\r
+end;\r
+\r
+procedure TfrmMain.acFileExitExecute(Sender: TObject);\r
+begin\r
+  PostMessage(SELF.Handle, WM_CLOSE, 0, 0);\r
+end;\r
+\r
+procedure TfrmMain.LoadVersion;\r
+var\r
+  l: TStrings;\r
+  i: Integer;\r
+  s: string;\r
+begin\r
+  l := TStringList.Create;\r
+  try\r
+    if not gpsbabel('-V', l) then Exit;\r
+\r
+    for i := 0 to l.Count - 1 do\r
+    begin\r
+      s := Trim(l.Strings[i]);\r
+      if (Copy(AnsiUpperCase(s), 1, 8) = 'GPSBABEL') then\r
+      begin\r
+        stbMain.Panels[0].Text := s;\r
+        stbMain.Panels[0].Width := stbMain.Canvas.TextWidth(s) + 32;\r
+      end;\r
+    end;\r
+\r
+  finally\r
+    l.Free;\r
+  end;\r
+end;\r
+\r
+procedure TfrmMain.acHelpAboutExecute(Sender: TObject);\r
+begin\r
+  frmAbout.ShowModal;\r
+end;\r
+\r
+procedure TfrmMain.chbInputDeviceClick(Sender: TObject);\r
+begin\r
+  if not(Sender is TCheckBox) then Exit;\r
+\r
+  if TCheckBox(Sender).Checked then\r
+  begin\r
+    edInputFile.Visible := False;\r
+    sbOpenFile.Visible := False;\r
+    cbInputDevice.Visible := True;\r
+    cbInputFormatDevice.Visible := True;\r
+  end\r
+    else\r
+  begin\r
+    cbInputFormatDevice.Visible := False;\r
+    cbInputDevice.Visible := False;\r
+    edInputFile.Visible := True;\r
+    sbOpenFile.Visible := True;\r
+  end;\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.StoreProfiles;\r
+var\r
+  s: string;\r
+begin\r
+  s := SysUtils.ExtractFilePath(edInputFile.Text);\r
+  if (s <> '') then\r
+    StoreProfile(OpenDialog.Tag, s);\r
+  s := SysUtils.ExtractFilePath(edOutputFile.Text);\r
+  if (s <> '') then\r
+    StoreProfile(SaveDialog.Tag, s);\r
+  StoreProfile(cbInputFormat.Tag, cbInputFormat.Text);\r
+  StoreProfile(cbOutputFormat.Tag, cbOutputFormat.Text);\r
+  StoreProfile(cbInputDevice.Tag, cbInputDevice.Text);\r
+  StoreProfile(cbInputFormatDevice.Tag, cbInputFormatDevice.Text); \r
+  StoreProfile(cbOutputDevice.Tag, cbOutputDevice.Text);\r
+  StoreProfile(cbOutputFormatDevice.Tag, cbOutputFormatDevice.Text); \r
+end;\r
+\r
+procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);\r
+begin\r
+  StoreProfiles;\r
+end;\r
+\r
+procedure TfrmMain.chbOutputDeviceClick(Sender: TObject);\r
+begin\r
+  if not(Sender is TCheckBox) then Exit;\r
+\r
+  if TCheckBox(Sender).Checked then\r
+  begin\r
+    edOutputFile.Visible := False;\r
+    sbSaveFile.Visible := False;\r
+    cbOutputFormatDevice.Visible := True;\r
+    cbOutputDevice.Visible := True;\r
+  end\r
+    else\r
+  begin\r
+    cbOutputDevice.Visible := False;\r
+    cbOutputFormatDevice.Visible := False;\r
+    sbSaveFile.Visible := True;\r
+    edOutputFile.Visible := True;\r
+  end;\r
+  CheckInput;\r
+end;\r
+\r
+procedure TfrmMain.acHelpReadmeExecute(Sender: TObject);\r
+begin\r
+  frmReadme.ShowModal;\r
+end;\r
+\r
+end.\r
\ No newline at end of file
diff --git a/gpsbabel/win32/gui-2/readme.dfm b/gpsbabel/win32/gui-2/readme.dfm
new file mode 100644 (file)
index 0000000..efc9d17
Binary files /dev/null and b/gpsbabel/win32/gui-2/readme.dfm differ
diff --git a/gpsbabel/win32/gui-2/readme.pas b/gpsbabel/win32/gui-2/readme.pas
new file mode 100644 (file)
index 0000000..d4b1a6b
--- /dev/null
@@ -0,0 +1,63 @@
+unit readme;\r
+\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+interface\r
+\r
+uses\r
+  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\r
+  ExtCtrls, StdCtrls, Buttons;\r
+\r
+type\r
+  TfrmReadme = class(TForm)\r
+    Memo: TMemo;\r
+    Panel1: TPanel;\r
+    BitBtn1: TBitBtn;\r
+    procedure FormDestroy(Sender: TObject);\r
+    procedure FormCreate(Sender: TObject);\r
+  private\r
+    { Private declarations }\r
+    FStr: TStream;\r
+  public\r
+    { Public declarations }\r
+  end;\r
+\r
+var\r
+  frmReadme: TfrmReadme;\r
+\r
+implementation\r
+\r
+{$R *.DFM}\r
+\r
+procedure TfrmReadme.FormDestroy(Sender: TObject);\r
+begin\r
+  FStr.Free;\r
+end;\r
+\r
+procedure TfrmReadme.FormCreate(Sender: TObject);\r
+begin\r
+  try\r
+    FStr := TFileStream.Create('README', fmOpenRead);\r
+    Memo.Lines.LoadFromStream(FStr);\r
+  except\r
+    FStr := nil;\r
+  end;\r
+end;\r
+\r
+end.\r
diff --git a/gpsbabel/win32/gui-2/template.po b/gpsbabel/win32/gui-2/template.po
new file mode 100644 (file)
index 0000000..fe5634c
--- /dev/null
@@ -0,0 +1,481 @@
+# SOME DESCRIPTIVE TITLE.\r
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\r
+# This file is distributed under the same license as the PACKAGE package.\r
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\r
+#\r
+msgid ""\r
+msgstr ""\r
+"Project-Id-Version: PACKAGE VERSION\n"\r
+"POT-Creation-Date: 2005-09-22 23:44\n"\r
+"PO-Revision-Date: 2005-09-22 23:44\n"\r
+"Last-Translator: Somebody <your.email@address.com>\n"\r
+"MIME-Version: 1.0\n"\r
+"Content-Type: text/plain; charset=UTF-8\n"\r
+"Content-Transfer-Encoding: 8bit\n"\r
+"X-Generator: dxgettext 1.2\n"\r
+\r
+#. frmAbout..Caption\r
+#: about.dfm:5\r
+msgid "About"\r
+msgstr ""\r
+\r
+#. frmAbout..Font.Name\r
+#: about.dfm:12\r
+#. frmAbout..pnClient..StaticText1..Font.Name\r
+#: about.dfm:72\r
+#. frmFilter..Font.Name\r
+#: filter.dfm:13\r
+#. frmMain..Font.Name\r
+#: main.dfm:11\r
+#. frmMain..Panel2..lbWhat..Font.Name\r
+#: main.dfm:238\r
+#. frmReadme..Font.Name\r
+#: readme.dfm:11\r
+msgid "MS Sans Serif"\r
+msgstr ""\r
+\r
+#. frmAbout..pnClient..Caption\r
+#: about.dfm:26\r
+msgid "... under construction"\r
+msgstr ""\r
+\r
+#. frmAbout..pnClient..StaticText1..Caption\r
+#: about.dfm:68\r
+msgid "GPSBabelGUI-2:"\r
+msgstr ""\r
+\r
+#. frmAbout..pnClient..StaticText2..Caption\r
+#: about.dfm:82\r
+msgid "The frontend for gpsbabel command line "\r
+"program"\r
+msgstr ""\r
+\r
+#. frmFilter..Caption\r
+#: filter.dfm:6\r
+msgid "Filter"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..Caption\r
+#: filter.dfm:27\r
+#. frmMain..Panel2..cbTracks..Caption\r
+#: main.dfm:393\r
+msgid "&Tracks"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..lbTimePlusMinus..Caption\r
+#: filter.dfm:35\r
+msgid "by"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..lbTimeDays..Caption\r
+#: filter.dfm:42\r
+msgid "day(s), "\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..lbTimeHours..Caption\r
+#: filter.dfm:49\r
+msgid "hour(s), "\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..lbTimeMinutes..Caption\r
+#: filter.dfm:56\r
+msgid "minute(s),"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..lbTimeSeconds..Caption\r
+#: filter.dfm:63\r
+msgid "second(s)"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackTitle..Hint\r
+#: filter.dfm:70\r
+msgid "Title for new tracks"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackTitle..Caption\r
+#: filter.dfm:72\r
+msgid "Tit&le"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..edTrackTitle..Text\r
+#: filter.dfm:84\r
+msgid "ACTIVE LOG # %Y%m%d"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackSplit..Hint\r
+#: filter.dfm:91\r
+msgid "Split track into several tracks depending on date of "\r
+"trackpoint"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackSplit..Caption\r
+#: filter.dfm:92\r
+msgid "&Split"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackTime..Hint\r
+#: filter.dfm:100\r
+msgid "Shift all tracks"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackTime..Caption\r
+#: filter.dfm:101\r
+msgid "&Move"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackStart..Hint\r
+#: filter.dfm:193\r
+msgid "Take only trackpoints starting at"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackStart..Caption\r
+#: filter.dfm:194\r
+msgid "Start at"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackStop..Caption\r
+#: filter.dfm:234\r
+msgid "stop at"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackPack..Hint\r
+#: filter.dfm:273\r
+msgid "Pack all tracks into one track (No duplicate "\r
+"timestamps)"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackPack..Caption\r
+#: filter.dfm:274\r
+msgid "&Pack (or)"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackMerge..Hint\r
+#: filter.dfm:283\r
+msgid "Merge all tracks into one track"\r
+msgstr ""\r
+\r
+#. frmFilter..gbTracks..cbTrackMerge..Caption\r
+#: filter.dfm:284\r
+msgid "Merge"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..Caption\r
+#: filter.dfm:295\r
+msgid "&Routes && Tracks"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..lbRouteSimplifyCount..Caption\r
+#: filter.dfm:303\r
+msgid "limit to"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..lbRouteSimplifyText..Caption\r
+#: filter.dfm:311\r
+msgid "Points"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..cbRouteSimplify..Hint\r
+#: filter.dfm:318\r
+msgid "Simplify routes and tracks by limited number of "\r
+"points"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..cbRouteSimplify..Caption\r
+#: filter.dfm:319\r
+msgid "Simplify"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Hint\r
+#: filter.dfm:328\r
+msgid "Upper limit of points for routes and "\r
+"tracks"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..edRoutesSimplifyMaxPoints..Text\r
+#: filter.dfm:333\r
+msgid "50 "\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..cbReverse..Hint\r
+#: filter.dfm:352\r
+msgid "Reverse routes and tracks"\r
+msgstr ""\r
+\r
+#. frmFilter..gbRoutes..cbReverse..Caption\r
+#: filter.dfm:353\r
+msgid "Reverse"\r
+msgstr ""\r
+\r
+#. frmFilter..pnBottom..btnOK..Caption\r
+#: filter.dfm:370\r
+msgid "OK"\r
+msgstr ""\r
+\r
+#. frmFilter..pnBottom..BitBtn1..Caption\r
+#: filter.dfm:406\r
+msgid "File based filters"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..Caption\r
+#: filter.dfm:426\r
+#. frmMain..Panel2..cbWaypoints..Caption\r
+#: main.dfm:373\r
+msgid "&Waypoints"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Hint\r
+#: filter.dfm:452\r
+msgid "Merge waypoints with duplicate locations"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDupLoc..Caption\r
+#: filter.dfm:453\r
+msgid "locations"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Hint\r
+#: filter.dfm:462\r
+msgid "Merge waypoints with duplicate \"short "\r
+"name\""\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDupNames..Caption\r
+#: filter.dfm:463\r
+msgid "\"short names\""\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDistance..Hint\r
+#: filter.dfm:472\r
+msgid "Merge waypoints separated by less then"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDistance..Caption\r
+#: filter.dfm:473\r
+msgid "Radius"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cobWayptMergeDist....Items.Strings\r
+#: filter.dfm:487\r
+msgid "Feet"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cobWayptMergeDist....Items.Strings\r
+#: filter.dfm:488\r
+#: filter.pas:163\r
+msgid "Miles"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptSort..Hint\r
+#: filter.dfm:505\r
+msgid "Sort waypoints by \"short name\" or by "\r
+"description"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptSort..Caption\r
+#: filter.dfm:506\r
+msgid "Sort"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDups..Hint\r
+#: filter.dfm:514\r
+msgid "Merge duplicate waypoints"\r
+msgstr ""\r
+\r
+#. frmFilter..gbWaypoints..cbWayptMergeDups..Caption\r
+#: filter.dfm:515\r
+msgid "Duplicatates"\r
+msgstr ""\r
+\r
+#. frmMain..Caption\r
+#: main.dfm:6\r
+msgid "GPSBabelGUI-2"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..lbInputFile..Caption\r
+#: main.dfm:78\r
+msgid "&Input file"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..lbOutputFile..Caption\r
+#: main.dfm:86\r
+msgid "Out&put file"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..lbInputFormat..Caption\r
+#: main.dfm:94\r
+msgid "Input &format"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..lbOutputFormat..Caption\r
+#: main.dfm:101\r
+msgid "Output f&ormat"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..chbInputDevice..Caption\r
+#: main.dfm:150\r
+#. frmMain..Panel1..chbOutputDevice..Caption\r
+#: main.dfm:199\r
+msgid "Device"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..cbInputDevice....Items.Strings\r
+#: main.dfm:162\r
+#. frmMain..Panel1..cbOutputDevice....Items.Strings\r
+#: main.dfm:211\r
+msgid "USB"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..cbInputDevice....Items.Strings\r
+#: main.dfm:163\r
+#. frmMain..Panel1..cbOutputDevice....Items.Strings\r
+#: main.dfm:212\r
+msgid "COM1"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..cbInputDevice....Items.Strings\r
+#: main.dfm:164\r
+#. frmMain..Panel1..cbOutputDevice....Items.Strings\r
+#: main.dfm:213\r
+msgid "COM2"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..cbInputDevice....Items.Strings\r
+#: main.dfm:165\r
+#. frmMain..Panel1..cbOutputDevice....Items.Strings\r
+#: main.dfm:214\r
+msgid "COM3"\r
+msgstr ""\r
+\r
+#. frmMain..Panel1..cbInputDevice....Items.Strings\r
+#: main.dfm:166\r
+#. frmMain..Panel1..cbOutputDevice....Items.Strings\r
+#: main.dfm:215\r
+msgid "COM4"\r
+msgstr ""\r
+\r
+#. frmMain..Panel2..lbWhat..Caption\r
+#: main.dfm:234\r
+msgid "What ?"\r
+msgstr ""\r
+\r
+#. frmMain..Panel2..cbRoutes..Caption\r
+#: main.dfm:384\r
+msgid "&Routes"\r
+msgstr ""\r
+\r
+#. frmMain..Panel2..btnFilter..Caption\r
+#: main.dfm:404\r
+#. frmMain..ActionList1..acFilterSelect..Caption\r
+#: main.dfm:907\r
+msgid "&Filter"\r
+msgstr ""\r
+\r
+#. frmMain..Panel2..btnProcess..Caption\r
+#: main.dfm:428\r
+#. frmMain..ActionList1..acConvert..Caption\r
+#: main.dfm:900\r
+msgid "let's go"\r
+msgstr ""\r
+\r
+#. frmMain..memoOutput..Font.Name\r
+#: main.dfm:455\r
+msgid "Fixedsys"\r
+msgstr ""\r
+\r
+#. frmMain..stbMain......Text\r
+#: main.dfm:473\r
+msgid "http://sourceforge.net/projects/gpsbabel"\r
+msgstr ""\r
+\r
+#. frmMain..OpenDialog..Filter\r
+#: main.dfm:480\r
+msgid "Garmin Mapsource|*.gdb|Garmin Mapsource mps|*.mps|All "\r
+"files|*.*"\r
+msgstr ""\r
+\r
+#. frmMain..ActionList1..acConvert..Category\r
+#: main.dfm:899\r
+#. frmMain..ActionList1..acFilterSelect..Category\r
+#: main.dfm:906\r
+msgid "Babel"\r
+msgstr ""\r
+\r
+#. frmMain..ActionList1..acFileExit..Category\r
+#: main.dfm:912\r
+msgid "File"\r
+msgstr ""\r
+\r
+#. frmMain..ActionList1..acFileExit..Caption\r
+#: main.dfm:913\r
+msgid "E&xit"\r
+msgstr ""\r
+\r
+#. frmMain..ActionList1..acHelpAbout..Category\r
+#: main.dfm:918\r
+#. frmMain..ActionList1..acHelpIntro..Category\r
+#: main.dfm:923\r
+#. frmMain..ActionList1..acHelpReadme..Category\r
+#: main.dfm:927\r
+msgid "Help"\r
+msgstr ""\r
+\r
+#. frmMain..ActionList1..acHelpAbout..Caption\r
+#: main.dfm:919\r
+msgid "&About"\r
+msgstr ""\r
+\r
+#. frmMain..ActionList1..acHelpIntro..Caption\r
+#: main.dfm:924\r
+msgid "&Intro"\r
+msgstr ""\r
+\r
+#. frmMain..ActionList1..acHelpReadme..Caption\r
+#: main.dfm:928\r
+#. frmReadme..Caption\r
+#: readme.dfm:6\r
+msgid "GPSBabel README"\r
+msgstr ""\r
+\r
+#. frmMain..MainMenu1..mnuFile..Caption\r
+#: main.dfm:937\r
+msgid "&File"\r
+msgstr ""\r
+\r
+#. frmMain..MainMenu1..mnuHelp..Caption\r
+#: main.dfm:943\r
+msgid "&Help"\r
+msgstr ""\r
+\r
+#: main.pas:249\r
+msgid "All files|*.*"\r
+msgstr ""\r
+\r
+#: main.pas:338\r
+msgid "|All files|*.*"\r
+msgstr ""\r
+\r
+#: main.pas:377\r
+msgid "File %s not found."\r
+msgstr ""\r
+\r
+#: main.pas:394\r
+msgid "File \"%s\" exists ! Overwrite ?"\r
+msgstr ""\r
+\r
+#: main.pas:395\r
+msgid "Warning"\r
+msgstr ""\r
+\r
+#: main.pas:420\r
+msgid "Could not run \"gpsbabel.exe\"!"\r
+msgstr ""\r
+\r
+#: main.pas:429\r
+msgid "Converted successfully from \"%s\" to "\r
+"\"%s\"."\r
+msgstr ""\r
+\r
+#: main.pas:430\r
+msgid "Success"\r
+msgstr ""\r
+\r
diff --git a/gpsbabel/win32/gui-2/utils.pas b/gpsbabel/win32/gui-2/utils.pas
new file mode 100644 (file)
index 0000000..f114227
--- /dev/null
@@ -0,0 +1,210 @@
+unit utils;\r
+\r
+{\r
+    Copyright (C) 2005 Olaf Klein, o.k.klein@t-online.de\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+}\r
+\r
+interface\r
+\r
+uses\r
+  gnugettextD4,\r
+  Windows, SysUtils, Classes, Registry;\r
+\r
+function gpsbabel(const CommandLine: string; Output: TStrings): Boolean;\r
+\r
+function GetShortName(const PathName: string): string;\r
+procedure StoreProfile(const Tag: Integer; const Value: string);\r
+function ReadProfile(const Tag: Integer): string;\r
+\r
+function BackupProperties(Instance: TObject; Properties: TStrings; Backup: TStringList): Boolean;\r
+procedure RestoreProperties(Instance: TObject; Backup: TStringList);\r
+\r
+implementation\r
+\r
+uses\r
+  common;\r
+\r
+function GetShortName(const PathName: string): string;\r
+var\r
+  buffer: array[0..4095] of Char;\r
+  len: DWORD;\r
+begin\r
+  len := Windows.GetShortPathName(PChar(PathName), @buffer, sizeof(buffer));\r
+  SetString(Result, buffer, len);\r
+end;\r
+\r
+function gpsbabel(const CommandLine: string; Output: TStrings): Boolean;\r
+var\r
+  hRead, hWrite: THandle;\r
+  ProcessInfo: TProcessInformation;\r
+  SecurityAttr: TSecurityAttributes;\r
+  StartupInfo: TStartupInfo;\r
+  sCmd: string;\r
+\r
+  BytesRead, BytesDone: DWORD;\r
+  buffer: packed array[0..512] of Char;\r
+  Error: DWORD;\r
+  s: string;\r
+\r
+begin\r
+  Result := False;\r
+   \r
+  sCmd := SysUtils.Format('%s %s ', [gpsbabel_exe, CommandLine]);\r
+\r
+{  i := WinExec(PChar(sCmd), SW_SHOWNORMAL);\r
+  if (i <> 33) then\r
+  begin\r
+    MessageBox(0, 'There was an error.', 'Uhps', MB_OK);\r
+    Exit;\r
+  end;\r
+}\r
+  SecurityAttr.nLength := sizeof (TSECURITYATTRIBUTES);\r
+  SecurityAttr.bInheritHandle := true;\r
+  SecurityAttr.lpSecurityDescriptor := nil;\r
+\r
+  if not CreatePipe(hRead, hWrite, @SecurityAttr, 0) then\r
+    raise eGPSBabelError.Create('Konnte "NamedPipe" nicht anlegen!');\r
+\r
+  try\r
+\r
+    if not FileExists(gpsbabel_exe) then\r
+      raise eGPSBabelError.Create('gpsbabel.exe wurde nicht gefunden!');\r
+\r
+    FillChar (StartupInfo, Sizeof (StartupInfo), #0);\r
+\r
+    StartupInfo.cb := Sizeof (StartupInfo);\r
+    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;\r
+    StartupInfo.wShowWindow := SW_HIDE and SW_SHOWMINNOACTIVE;\r
+    StartupInfo.hStdInput := GetStdHandle (STD_INPUT_HANDLE);\r
+    StartupInfo.hStdOutput:= hWrite;\r
+    StartupInfo.hStdError := hWrite;\r
+\r
+    FillChar(ProcessInfo, SizeOf(ProcessInfo), #0);\r
+\r
+    if not CreateProcess (\r
+      nil,                // lpApplicationName    // pointer to name of executable module\r
+      // sCmd includes both the exec name and the command line parms in this call\r
+      pchar (sCmd),       // lpCommandLine,       // pointer to command line string\r
+      nil,                // lpProcessAttributes, // pointer to process security attributes\r
+      nil,                // lpThreadAttributes,  // pointer to thread security attributes\r
+      true,               // bInheritHandles,     // handle inheritance flag\r
+      CREATE_NEW_CONSOLE, // dwCreationFlags,     // creation flags\r
+      nil,                // lpEnvironment,       // pointer to new environment block\r
+      nil,                // lpCurrentDirectory,  // pointer to current directory name\r
+      StartupInfo,        // lpStartupInfo,       // pointer to STARTUPINFO\r
+      ProcessInfo)        // lpProcessInformation // pointer to PROCESS_INFORMATION\r
+      then\r
+    begin\r
+      Error := GetLastError;\r
+      raise eGPSBabelError.CreateFmt(\r
+        'gpsbabel.exe konnte nicht gestartet werden (Fehler %d).', [Error]);\r
+    end;\r
+\r
+    while (WaitforSingleObject (ProcessInfo.hProcess, 0)) <> WAIT_OBJECT_0 do sleep(100);\r
+\r
+    if not GetExitCodeProcess(ProcessInfo.hProcess, Error) then Error := 0;\r
+\r
+    if ((Error <> 0) and (Error <> 1)) then\r
+      raise eGPSBabelError.CreateFmt('Schade, "gpsbabel.exe" verlies uns mit Fehler 0x%x (%d)', [Error, Error]);\r
+\r
+    s := '';\r
+\r
+    PeekNamedPipe(hRead, nil, 0, nil, @BytesRead, nil);\r
+\r
+    while (BytesRead > 0) do\r
+    begin\r
+      ReadFile(hRead, Buffer, SizeOf(buffer)-1, BytesDone, nil);\r
+      buffer[BytesDone] := #0;\r
+      s := s + string(buffer);\r
+\r
+      Dec(BytesRead, BytesDone);\r
+    end;\r
+\r
+    Output.Clear;\r
+    Output.SetText(PChar(s));\r
+\r
+    Result := True;\r
+\r
+  finally\r
+    CloseHandle (hRead);\r
+    CloseHandle (hWrite);\r
+  end;\r
+end;\r
+\r
+procedure StoreProfile(const Tag: Integer; const Value: string);\r
+var\r
+  reg: TRegistry;\r
+  str: string;\r
+begin\r
+  if (Tag <= 0) or (Tag > High(Profile)) then Exit;\r
+\r
+  str := Profile[Tag];\r
+  reg := TRegistry.Create;\r
+  try\r
+    reg.RootKey := HKEY_CURRENT_USER;\r
+    if reg.OpenKey('\SOFTWARE\GPSBabel', True) then\r
+    begin\r
+      reg.WriteString(str, Value);\r
+    end;\r
+  finally\r
+    reg.Free;\r
+  end;\r
+end;\r
+\r
+function ReadProfile(const Tag: Integer): string;\r
+var\r
+  reg: TRegistry;\r
+  str: string;\r
+begin\r
+  if (Tag <= 0) or (Tag > High(Profile)) then Exit;\r
+\r
+  str := Profile[Tag];\r
+\r
+  reg := TRegistry.Create;\r
+  try\r
+    reg.RootKey := HKEY_CURRENT_USER;\r
+    if reg.OpenKey('\SOFTWARE\GPSBabel', True) then\r
+    begin\r
+      try\r
+        Result := reg.ReadString(str);\r
+      except\r
+        Result := '';\r
+      end;\r
+    end;\r
+  finally\r
+    reg.Free;\r
+  end;\r
+end;\r
+\r
+\r
+function BackupProperties(Instance: TObject; Properties: TStrings; Backup: TStringList): Boolean;\r
+var\r
+  List: TStringList;\r
+begin\r
+  List := TStringList.Create;\r
+  try\r
+    Backup.Assign(List);\r
+  finally\r
+    List.Free;\r
+  end;\r
+end;\r
+\r
+procedure RestoreProperties(Instance: TObject; Backup: TStringList);\r
+begin\r
+end;\r
+\r
+end.\r